Dependency injection and ASP.Net Membership Providers - asp.net-mvc

I am in the process of creating a custom membership provider for an ASP.Net MVC website. The provider is being created as a separate class as part of a bigger library. There is a need for the back-end data store to be flexible as it could be an Xml File or SQL database. My initial thought was to create an interface for the data store and inject this into provider using dependency injection.
The end result is required is that a developer can inherit the data store interface and provide the required methods to update the data, which will then be used by the custom membership providers.
However through my own lack of skill I can't figure out how to inject the class into the membership provider when adding it to the website? What needs to be done to link the data store to the provider? What would be the simplest way to enable this in the website?

If you are configuring the custom membership providers via the <membership> element in the Web.config file, then I can see the issues you will have with dependency injection.
The providers are constructed and managed by the framework, and there is no opportunity for you to intercept that construction to provide additional dependency injection for the IDataStore interface.
If my assumption is correct, then what you can do is override the Initialize() method in your custom provider, and do the dependency injection there. You can have a custom name/value setting in the provider configuration which points to a type that implements IDataStore, which is passed as part of a dictionary to the Initialize() method.
Then, you activate an instance of the data store type and set it on the appropriate property:
public class MyMembershipProvider : MembershipProvider
{
public IDataStore DataStore
{
get;
set;
}
public override Initialize(string name, NameValueCollection config)
{
var dataStoreType = config["dataStoreProvider"];
if (!String.IsNullOrEmpty(dataStoreType))
{
var type = Type.GetType(dataStoreType);
DataStore = (IDataStore) Activator.CreateInstance(type);
}
}
}
Initialize() will be called by the framework after it constructs an instance of your provider, so that is the perfect place to do any additional setup work such as this.
For testing scenarios, you just set the data store property on the provider instance itself, as you will be constructing it directly in your tests.

Isn't this better? I use it with MVC3 and ninject. It's enough to add a property to your custom membership provider class. Remember to add "using System.Web.Mvc;" on top.
public IRepository Repository
{
get
{
return DependencyResolver.Current.GetService<IRepository>();
}
}

The simplest way to do dependency injection that I've seen (and actually the only one I've used so far...) is to have a constructor of your dependent class take the interface as a parameter, and assign it to a private field. If you want, you can also add a "default" constructor, which chains to the first one with a default value.
Simplified, it would look something like this:
public class DependentClass
{
private IDataStore _store;
// Use this constructor when you want strict control of the implementation
public DependentClass(IDataStore store)
{
this._store = store;
}
// Use this constructor when you don't want to create an IDataStore instance
// manually every time you create a DependentClass instance
public DependentClass() : this(new DefaultDataStore()) { }
}
The concept is called "Constructor chaining", and there's a lot of articles on the web on how to do it. I find this tutorial very explanatory of the DI pattern.

Related

How to mock the Context based on an interface when using Ninject?

I have my normal Entity Framework context, which is like this:
public class LikvidoWebsitesApiContext : IdentityDbContext<ApplicationUser>, ILikvidoWebsitesApiContext
{
// code
}
I have made an interface, which has my DBSets.
In my normal solution, I set it up in Ninject like this:
kernel.Bind<ILikvidoWebsitesApiContext>().To<LikvidoWebsitesApiContext>().InRequestScope();
I use the context in my services by adding the ILikvidoWebsitesApiContext inside the constructor, and then I can use the database.
My question is: how do I set this up in the unit Test?
I have tried to do the following:
kernel.Bind(typeof(ILikvidoWebsitesApiContext))
.To(typeof(Mock<LikvidoWebsitesApiContext>))
.Register(true);
(Using the Moq framework)
However, this gives the:
System.InvalidCastException: 'Unable to cast object of type 'Moq.Mock`1[Likvido.Domain.Services.Data.LikvidoWebsitesApiContext]' to type 'Likvido.Domain.Services.Data.ILikvidoWebsitesApiContext'.'
Which do make sense, but I am very unsure how to fix it?
After a quick look at the Ninject wiki I came across
Providers, Factory Methods and the Activation Context
Where they show how to use a Provider to build up instances.
Following the suggestion in the wiki it was advised to extend Provider<T> which includes strong typing.
public MoqContextProvider : Provider<ILikvidoWebsitesApiContext> {
protected override ILikvidoWebsitesApiContext CreateInstance(IContext context) {
var mock = new Mock<ILikvidoWebsitesApiContext>();
// Set up of mock members
return mock.Object;
}
}
And then it is just a matter of plugging into the container
kernel.Bind<ILikvidoWebsitesApiContext>().ToProvider(new MoqContextProvider());
There was also a suggestion about using Factory Methods
A lighter weight alternative to writing IProvider implementations is to bind a service to a delegate method.
kernal.Bind<ILikvidoWebsitesApiContext>()
.ToMethod(context => {
var mock = new Mock<ILikvidoWebsitesApiContext>();
// Set up of mock members
return mock.Object;
});
The provided Func will be bound to the service type for deferred binding and called later when a new instance of the service (i.e. ILikvidoWebsitesApiContext) is required.
Remember that when using Moq you need to set up the desired behavior of the mocks.

AutoFac Injection into attribute

So I have a need for injecting a number of different services into an authorization attribute I'm using. For simplicity I will leave this to show the configuration manager.
public class FeatureAuthorizeAttribute : AuthorizeAttribute
{
public IConfigurationManager ConfigurationManager;
private readonly string _feature;
public FeatureAuthorizeAttribute(string feature)
{
_feature = feature;
var test = ConfigurationManager.GetCdnPath();
}
}
Which would be used as follows
[FeatureAuthorize("Admin")]
I have tried to use constructor injection
public FeatureAuthorizeAttribute(string feature, IConfigurationManager configurationManager)
{
ConfigurationManager = configurationManager;
_feature = feature
}
However this just causes an error when I attempt
[FeatureAuthorize("Admin", IConfigurationManager)]
Which seems like the wrong way to go about it in the first place. I'm assuming that I need to register my custom authorization attribute with the container to get it to start picking up
Instead of trying to use Dependency Injection with attributes (which you can't do in any sane, useful way), create Passive Attributes.
Specifically, in this case, assuming that this is an ASP.NET MVC scenario, you can't derive from AuthorizeAttribute. Instead, you should make your Authorization service look for your custom attribute, and implement IAuthorizationFilter. Then add the filter to your application's configuration.
More details can be found in this answer: https://stackoverflow.com/a/7194467/126014.

programmatically injecting a different bean implementation

I have a requirement, my current project is with ejb3, jpa and jsf. I have a core development project and customer specific project. In the customer specific project, we planned to inherit the core classes and extend or override the core functionality. So we planned to create the customer specific classes with some customer prefix. So in the final war file, we will have the core class and all customer prefix classes. For example, if Authenticator is a core class and XXAuthenticator, YYAuthenticator are customer specific classes exist in the build. So, for example if i have a line of code in a bean like this:
#Inject Authenticator authenticator;
Can i programmatically and/or dynamically inject the inherited classes based on some logic like logged in user has a customer specific functionality.
what i am expecting is, i dont want to change the above line to inject, because it will be big change in every class. But expecting some kind of dynamic logic or configuration file to change the core class injection to customer specific class..
So finally with out touching the #Inject Authenticator authenticator; line. Can I inject the xxAuthenticator or YYAuthenticator through some logic? We dont have Spring in project technology stack.. So please suggest me with out spring only.. Thanks in advance
It sounds like your use case is more around Qualifiers. If a user follows a certain, you should be injecting different qualified versions of classes to use, no?
#Inject
private Instance<SomeService> someServiceInstance;
// later on...
SomeService someService = null;
if(someCondition) {
someService = someServiceInstance.select(new FooLiteral()).get();
}
else {
someService = someServiceInstance.select(new BarLiteral()).get();
}
Where FooLiteral and BarLiteral are annotation literals for #Foo and #Bar, which are qualifiers.
In CDI this is done with "producer methods".
It would look like this:
#ApplicationScoped
public class AuthenticatorProducer {
private Authenticator xxAuthenticator; // = ...
private Authenticator yyAuthenticator; // = ...
#Produces
public Authenticator getAuthenticator() {
if (someCondition) {
return xxAuthenticator;
} else {
return yyAuthenticator;
}
}
}
No need to change injection points and Authenticators don't have to be CDI beans themselves.

Unity Custom Membership Dependency Not Working

I can't seem to figure out how to get dependency injection to work in a custom membership provider. I'm aware that the membership provider base class is managed deep in ASP.NET, but there should be some way to get dependency injection to work on private data members.
I'm using Unity and see this issue only in my membership and role providers
my issue is two fold:
The application complains that it doesn't have a parameterless
constructor for "MyMembershipProvider"
even if I try this: https://stackoverflow.com/a/9815425/595335, security service is null in the ValidateUser method
public class MyMembershipProvider : MembershipProvider
{
public ISecurityService securityService;
public MyMembershipProvider(ISecurityService securityService)
{
this.securityService = new SecurityService();
}
public override bool ValidateUser(string username, string password)
{
User user = securityService.GetUserByUsername(username);
...ommited...
}
It may not be as ideal, but you might need to use property injection instead of constructor injection.
The problem is that your provider is created by a static class. Since static classes are not "instantiated" and live for the lifetime of the app, there is no way to allow your DI framework to instantiate a static class.
There are potential workarounds, but you can't use constructor injection. These workarounds are also brittle and overly complex. In short, it's a PITA and is just not worth the effort. You would probably save yourself a lot of headache by either forgettinga bout DI in a membership provider, or forgetting about using Membership and roll a custom IIdentity and IPrincipal solution.

MVC Custom Attributes and Binding

I've got a project where we have our own customer registration and account management system, but certain elements of the application link to 3rd party services. These services have common functionality e.g. creating an account in their own DB, but the underlying implementation will be different for how to interactive with the third party services.
What I've done so far is create a CustomerRepository which implements ICustomerRepository. This contains all our own specific requirements. ICustomerRepository also has definitions for the common methods that all third parties will have, but these methods are set to virtual in the CustomerRepository class, which throws exceptions if they're called, requiring you to implement them in the third party classes.
Then from this, I have:
ThirdPartyACustomer : CustomerRepository, IThirdPartyACustomer
ThirdPartyBCustomer : CustomerRepository
As you can probably guess, both of those sub classes inherit and override the virtual methods, with the exception of ThirdPartyACustomer which also implements additional methods that are specific to that particular type of third party user (e.g. there might be a place where the user can edit specific features related to third party A, which third party B doesn't offer.
Now, with that out of the way, the real basis of my question:
Some of the processes (controllers) in my application can use the CustomerRepository without any problems as they only need our core functionality.
Other processes in the app require a particular type of ICustomerRepository to be passed. Anything that calls a method that was defined as virtual in CustomerRepository will need to pass either ThirdPartyACustomer or ThirdPartyBCustomer so that the correct implementation is called.
Originally in this initialisation of this type of controller I'd do something like:
public RegistrationController()
{
ICustomerRepository _customerRepository = GetCustomerRepository();
}
where GetCustomerRepository() had some logic that determined which type of ThirdParty to use, based on the subdomain, for example.
Now, what I'm thinking is that I improve this by creating a custom attribute, along the lines of this:
[ThirdPartyDependent]
class RegistrationController
{
public RegistrationController(ICustomerRepository customerRepository)
{
_customerRepository = customerRepository;
}
}
and move the population of customerRepository parameter into that attribute, e.g. the logic in GetCustomerRepository would happen in there.
I'm fairly sure something like this is doable and seems to make sense for testing purposes, but not quite sure of what I should be googling for, or whether there is a better way to do things, so looking for some guidance from someone more experienced with MVC.
That's the responsibility of your DI framework. For example Ninject provides you access to the HttpContext when configuring the dependencies, so you could pick the proper implementation based on some HttpContext value. For example:
kernel.Bind<ICustomerRepository>().ToMethod(ctx =>
{
if (HttpContext.Current.... Test something on the request or domain or whatever)
{
return new ThirdPartyACustomer();
}
return ThirdPartyBCustomer();
});
and then of course your controller will be totally agnostic. All that a controller should care is that it gets injected some repository which obeys a given contract:
public class RegistrationController: Controller
{
private readonly ICustomerRepository _customerRepository;
public RegistrationController(ICustomerRepository customerRepository)
{
_customerRepository = customerRepository;
}
}

Resources