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?
The ASP.NET membership provider is a feature that enables ASP.NET developers to create Web sites that allow users to create unique user name and password combinations. With this facility, any user can establish an account with the site, and sign in for exclusive access to the site and its services.
ASP.NET Core supports the dependency injection (DI) software design pattern, which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies. For more information specific to dependency injection within MVC controllers, see Dependency injection into controllers in ASP.NET Core.
Dependency injection (also known as DI) is a design pattern in which a class or object has its dependent classes injected (passed to it by another class or object) rather than create them directly. Dependency injection facilitates loose coupling and promotes testability and maintenance.
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>(); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With