I want custom UserNamePasswordValidator in my orchard project.
Like this,How can i injection IUserService? thank you.
public class CustomUserNameValidator: UserNamePasswordValidator
{
private IUserSevice m_UserService;
public override void Validate(string userName, string password)
{
if (null == userName || null == password)
{
throw new ArgumentNullException();
}
if(!m_UserService.CheckUser(userName,password))
{
throw new SecurityTokenException("Unknown Username or Password");
}
}
}
There's an excellent article in the docs about dependency injection.
You basically need to build and implement an interface like this:
public interface ICustomUserNameValidator : IDependency{}
Afterwards you can inject it wherever you want.
public class MyPartDriver : ContentPartDriver
{
public MyPartDriver(ICustomerUserNameValidator validator)
{
}
}
Related
I've got three projects:
UI
PluginManager
PluginOne
PluginTwo
Inside my Plugin Manager a create a simple plugin interface:
public interface IPlugin<T>
{
void sayMessage(T message);
T createMessage();
}
So, in my other projects I've two IPlugin implementation:
In porject PluginOneProject -->
-------------------------------
public class PluginOne : IPlugin<IntMessage>
{
public void sayMessage(IntMessage message)
{
System.Console.WriteLine(message.ToString());
}
}
where:
public class IntMessage
{
private int message;
public IntMessage(int message)
{
this.message = message;
}
public override string ToString()
{
return this.message.ToString();
}
}
In porject PluginTwoProject -->
-------------------------------
public class PluginTwo : IPlugin<StringMessage>
{
public void sayMessage(StringMessage message)
{
System.Console.WriteLine(message.ToString());
}
}
where:
public class StringMessage
{
private String message;
public StringMessage(String message)
{
this.message = message;
}
public override string ToString()
{
return this.message.ToString();
}
}
Obviously, I've added the corresponding project references.
So, in my UI porject I've NInject, and I perform this convention mapping:
kernel.Bind(b => b.FromAssembliesMatching("*")
.SelectAllClasses()
.InheritedFrom(typeof(IPlugin<>))
.BindAllInterfaces()
);
The graph is built correctly.
So, I don't know how to get an instance of PluginOne, or PluginTwo from UI project.
I'm trying to use this code, however, I've a problem with generic interfaces...
foreach (IPlugin<?> plugin in kernel.GetAll(typeof(IPlugin<>)))
{
plugin.sayMessage(plugin.createMessage());
}
Unfortunately, you must request a specific interface from Ninject, so you must request either IPlugin<IntMessage> or IPlugin<StringMessage>.
I would suggest trying to refactor your app so that you can request a more generic interface, such as IPlugin, and/or create a message interface like IMessage that each message implements. It's not clear from your question what you're trying to accomplish.
The situation
I'm building a web application using the in the title mentioned techniques. This application will something like a CMS system for multiple clients. The client has to login to this system using his company name and login credentials.
With the provided company name, I connect to a database (static DbContext, same connection string every time) where all clients database information is stored and search for this clients specific database(every client has his own with exact same design) login information. That all works fine.
Now here is the tricky part. To continue the login procedure I need to somehow inject or lazy load the repository using the other DbContext with a connection string that is build up from the result of the other database.
What I have
2 DbContexts generated from an existing database, one static and one if possible dynamic.
Then the generic repository classes/interfaces:
public interface IRepository
{
void Submit();
}
public interface IRepository<TEntity, TContext> : IRepository
where TEntity : class
where TContext : DbContext
{
//crud stuff
}
public abstract class GenericRepository<TEntity, TContext> : IRepository<TEntity, TContext>
where TEntity : class
where TContext : DbContext
{
private TContext _dataContext;
private IUnitOfWork _unitOfWork;
private readonly IDbSet<TEntity> dbset;
protected GenericRepository(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
_unitOfWork.Register(this);
}
}
Unit of work class/interface
public interface IUnitOfWork
{
void Register(IRepository repository);
void Commit();
}
public class UnitOfWork : IUnitOfWork
{
private readonly Dictionary<string, IRepository> _repositories;
private HttpContextBase _httpContext;
public UnitOfWork(HttpContextBase httpContext)
{
_httpContext = httpContext;
}
public void Register(IRepository repository)
{
_repositories.Add(repository.GetType().Name, repository);
}
public void Commit()
{
_repositories.ToList().ForEach(x => x.Value.Submit());
}
}
Then a context/entity specific repository
public class EmployeeRepository : GenericRepository<tbl_Medewerker, CustomerDbEntities>, IEmployeeRepository
{
public EmployeeRepository(IUnitOfWork unitOfWork)
: base(unitOfWork)
{
}
}
public interface IEmployeeRepository : IRepository<tbl_Medewerker, CustomerDbEntities>
{
}
Then the service that implements the repository
public interface IEmployeeLoginService
{
tbl_Medewerker GetEmployeeByLogin(string username, string password);
tbl_Medewerker GetEmployeeByID(Guid id);
}
public class EmployeeLoginService : IEmployeeLoginService
{
private readonly IEmployeeRepository _employeeRepository;
public EmployeeLoginService(IEmployeeRepository employeeRepository)
{
_employeeRepository = employeeRepository;
}
public tbl_Medewerker GetEmployeeByLogin(string username, string password)
{
return _employeeRepository.Get(e => e.MedewerkerNaam.ToLower() == username.ToLower() && e.Password == password);
}
public tbl_Medewerker GetEmployeeByID(Guid id)
{
return _employeeRepository.GetById(id);
}
}
Finally the controller that implements that service and uses it in the login action
public class AccountController : BaseController
{
IConnectionService _connectionService;
IEmployeeLoginService _employeeService;
public AccountController(IConnectionService connectionService, IEmployeeLoginService employeeService)
{
_connectionService = connectionService;
_employeeService = employeeService;
}
[AllowAnonymous, HttpPost]
public ActionResult Login(LoginModel login)
{
if ((Settings)Session["Settings"] == null)
{
Settings settings = new Settings();
settings.company = _connectionService.GetCompanyName(login.CompanyName);
if (settings.company != null)
{
settings.licence = _connectionService.GetLicenceByCompanyID(settings.company.Company_id);
if (settings.licence != null)
{
settings.connectionStringOrName = string.Format(#"Data Source={0};Initial Catalog={1};User ID={2};Password={3};Application Name=EntityFrameworkMUE", settings.licence.WS_DatabaseServer, settings.licence.WS_DatabaseName, settings.licence.WS_DatabaseUID, settings.licence.WS_DatabasePWD);
Session["Settings"] = settings;
settings.user = _employeeService.GetEmployeeByLogin(login.UserName, login.Password);
if (settings.user != null)
{
FormsAuthentication.SetAuthCookie(string.Format("{0},{1}", settings.company.Company_id.ToString(), settings.user.Medewerker_ID.ToString()) , login.RememberMe);
return RedirectToAction("index", "home");
}
}
}
}
else
{
return RedirectToAction("index", "home");
}
return View();
}
}
And of course the autofac bootstrapper:
private static void SetAutoFacContainer()
{
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterType(typeof(UnitOfWork)).As(typeof(IUnitOfWork)).InstancePerHttpRequest();
builder.RegisterAssemblyTypes(typeof(UserRepository).Assembly)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces().InstancePerHttpRequest();
builder.RegisterAssemblyTypes(typeof(ConnectionService).Assembly)
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces().InstancePerHttpRequest();
builder.Register(c => new HttpContextWrapper(HttpContext.Current)).As<HttpContextBase>().InstancePerLifetimeScope();
builder.RegisterModule(new AutofacWebTypesModule());
builder.Register(att => new AuthorizeFilter(att.Resolve<IConnectionService>(), att.Resolve<IEmployeeLoginService>())).AsAuthorizationFilterFor<Controller>().InstancePerHttpRequest();
builder.RegisterFilterProvider();
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
My idea how to do this, is setting a session variable with the connection string after data retrieval from the one static database where the info is stored and inject session in the unit of work and somehow use it there, but I can't wrap my head around it.
The question(s):
Am I heading in the right direction trying to achieve this, or even is it possible? If not what steps would you take to achieve this
I know it's a long read I hope you guys can help me, I'm quite new to using these techniques all together. Thanks in advance - I really appreciate it!
Your on the right track, I have used
var mtc = new MultitenantContainer(container.Resolve<ITenantIdentificationStrategy>(), container);
DependencyResolver.SetResolver(new AutofacDependencyResolver(mtc));
The identification strategy would be based on the logged in user. With defaults for when they aren't logged in.
public class CompanyNameIdentificationStrategy : ITenantIdentificationStrategy
{
public bool TryIdentifyTenant(out object tenantId)
{
var context = HttpContext.Current;
if(context != null)
{
var myUser = context.User as MyUserObject;
if(myUser != null)
{
tenantId = myUser.CompanyName;
return true;
}
}
return false;
}
}
Then you add to your autofact setup:
var s = c.Resolve<ITenantIdentificationStrategy>();
object id;
if (s.TryIdentifyTenant(out id) && id != null)
{
return id;
}
return "default";
}).Keyed<string>("CompanyName");
builder.Register<Settings>(c =>
{
var companyName = c.ResolveKeyed<string>("companyName");
if (companyName == "default")
{
return new DefaultSettings();
}
var settings = new Settings();
return settings;
}).InstancePerLifetimeScope();
You can resolve stuff inside these code blocks. I would probably setup a keyed default settings, and then when the user is logged in the settings would switch to their setup and the rest of the application should work.
I'm using SpecFlow with Nunit and I'm trying to setup my enviroment tests using TestFixtureSetUpAttribute, but it's never called.
I already tried to use MSTests and ClassInitialize attribute, but the same happen. The function isn't called.
Any ideas Why?
[Binding]
public class UsersCRUDSteps
{
[NUnit.Framework.TestFixtureSetUpAttribute()]
public virtual void TestInitialize()
{
// THIS FUNCTION IS NEVER CALLER
ObjectFactory.Initialize(x =>
{
x.For<IDateTimeService>().Use<DateTimeService>();
});
throw new Exception("BBB");
}
private string username, password;
[Given(#"I have entered username ""(.*)"" and password ""(.*)""")]
public void GivenIHaveEnteredUsernameAndPassword(string username, string password)
{
this.username = username;
this.password = password;
}
[When(#"I press register")]
public void WhenIPressRegister()
{
}
[Then(#"the result should be default account created")]
public void ThenTheResultShouldBeDefaultAccountCreated()
{
}
Solution:
[Binding]
public class UsersCRUDSteps
{
[BeforeFeature]
public static void TestInitialize()
{
// THIS FUNCTION IS NEVER CALLER
ObjectFactory.Initialize(x =>
{
x.For<IDateTimeService>().Use<DateTimeService>();
});
throw new Exception("BBB");
}
private string username, password;
[Given(#"I have entered username ""(.*)"" and password ""(.*)""")]
public void GivenIHaveEnteredUsernameAndPassword(string username, string password)
{
this.username = username;
this.password = password;
}
[When(#"I press register")]
public void WhenIPressRegister()
{
}
[Then(#"the result should be default account created")]
public void ThenTheResultShouldBeDefaultAccountCreated()
{
}
Your TestInitialize is not called because it is inside your Steps class and not inside in an Unit Tests (because the actual unit test is inside the .cs which is generated from your .feature file).
SpecFlow has it's own test-lifetime events which are called hooks, these are all the predefined hooks:
[BeforeTestRun] / [AfterTestRun]
[BeforeFeature] / [AfterFeature]
[BeforeScenario] / [AfterScenario]
[BeforeScenarioBlock] / [AfterScenarioBlock]
[BeforeStep] / [AfterStep]
Note that this allows for greater flexibility in setup. For additional information see the documentation.
Based on the fact that you want to use the TestFixtureSetUp attribute you will probably need the BeforeFeature hook which will be called once before each feature, so you need to write:
[Binding]
public class UsersCRUDSteps
{
[BeforeFeature]
public static void TestInitialize()
{
ObjectFactory.Initialize(x =>
{
x.For<IDateTimeService>().Use<DateTimeService>();
});
throw new Exception("BBB");
}
//...
}
Note that the [BeforeFeature] attribute needs a static method.
You should also note that if you are using the VS integration there is an project item type called SpecFlow Hooks (event bindings) which creates a binding class with some predefined hooks to help you get started.
I am trying to write a pointcut and advice which could print a string from following method -
public CustomerDto getCustomer(Integer customerCode){
CustomerDto customerDto = new CustomerDto();
String emailID =getEmailAddress();
customerDto.setEmailAddress(emailID);
customerDto.setEmployer(getEmployer());
customerDto.setSpouseName(getSpouse());
return customerDto;
}
I am unable to figure out a way by which a pointcut look at String emailID and then print the value of the same in an advice.
Maybe you need something like the following:
public privileged aspect LocalMethodCallAspect {
private pointcut localMethodExecution() : withincode(public CustomerDto TargetClass.getCustomer(Integer)) &&
call(private String TargetClass.getEmailAddress());
after() returning(String email) : localMethodExecution()
{
System.out.println(email);
}
}
Where TargetClass is a class containing getCustomer() and getEmailAddress() methods.
Or the same using #AspectJ:
#Aspect
public class LocalMethodCallAnnotationDrivenAspect {
#Pointcut("withincode(public CustomerDto TargetClass.getCustomer(Integer)) && " +
"call(private String TargetClass.getEmailAddress())")
private void localMethodExecution() {
}
#AfterReturning(pointcut="localMethodExecution()",returning="email")
public void printingEmail(String email) {
System.out.println(email);
}
}
I am not sure how to use StructureMap to scan for all repositories in a particular namespace. Most repositories take the form:
namespace CPOP.Infrastructure.Repositories
{
public class PatientRepository : LinqRepository<Patient>, IPatientRepository
{
}
}
namespace CPOP.Infrastructure.Repositories
{
public class LinqRepository<T> : Repository<T>, ILinqRepository<T>
{
}
}
namespace CPOP.Domain.Contracts.Repositories
{
public interface IPatientRepository : ILinqRepository<Patient>
{
}
}
I tried:
x.Scan(scanner =>
{
scanner.Assembly(Assembly.GetExecutingAssembly());
scanner.ConnectImplementationsToTypesClosing(typeof(ILinqRepository<>));
})
But, it only picks up the LinqRepository class. What's the best way to pick up the various repositories I'll be dumping in there?
And, as per Joshua's reuest, here's an example of use:
namespace CPOP.ApplicationServices
{
public class PatientTasks : IPatientTasks
{
private readonly IPatientRepository _patientRepository;
public PatientTasks(IPatientRepository patientRepository)
{
_patientRepository = patientRepository;
}
public Patient GetPatientById(int patientId)
{
int userId; // get userId from authentication mechanism
return _patientRepository.FindOne(new PatientByIdSpecification(patientId));
}
public IEnumerable<Patient> GetAll()
{
int userId; // get userId from authentication mechanism
return _patientRepository.FindAll();
}
}
}
This can be done with just one line of code in your configuration. Assuming you have this:
Entities:
- Customer
- Order
And have a generic repository model like this:
Repository : IRepository
And have a app services that look like:
public AppService(IRepository<Customer> custRepo, IRepository<Order> orderRepo)
You would have something like this. Notice the bit about using the scanner to hook up your custom repositories.
public class SmRegistry : Registry
{
public SmRegistry()
{
For(typeof (IRepository<>))
.Use(typeof (Repository<>));
//using this will find any custom repos, like CustomerRepository : Repository<Customer>
//Scan(scanner =>
// {
// scanner.TheCallingAssembly();
// scanner.ConnectImplementationsToTypesClosing(typeof (IRepository<>));
// });
}
}
Assuming your Repositories are defined in some other assembly from your application, you can use Registries to hook it all together. Check out this post:
http://blog.coreycoogan.com/2010/05/24/using-structuremap-to-configure-applications-and-components/
Something like:
Assembly ass = Assembly.GetCallingAssembly();
Container.Configure(x => x.Scan(scan =>
{
scan.Assembly(ass);
scan.LookForRegistries();
}));
Then the Registry class:
public sealed class MyRegistry : Registry
{
...