MVC5 Identity with DI (Removing Service Locator anti-pattern) - c#

I am trying to remove the Service Locator Anti Pattern that comes by default with a new MVC5 project. I am attempting to implement DI instead using Ninject. I have come upon the following guide which is meant for unity, not an MVC5 application.
http://tech.trailmax.info/2014/09/aspnet-identity-and-ioc-container-registration/
From what I can tell, there is not too much difference in code between that article and a new MVC5 application. However there is one thing that I cannot seem to figure out what to do with.
In the article I provided above exists the following method
private static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<ApplicationDbContext>();
container.RegisterType<ApplicationSignInManager>();
container.RegisterType<ApplicationUserManager>();
}
I am trying to understand what this container is and what I would register my classes to in MVC5. Do I need to register my classes to some container to begin with? Still learning here and I'm quite new to MVC5 and Identity so any help is most appreciated.

The container contains configuration settings for each abstraction and its implementation. The container is used to create dependencies and inject them automatically when required. Whenever there is a need of instance of an abstraction, the container provides that to the requester. It automatically creates objects based on request and inject them when required. The container helps to manage dependencies with in the application in a simple and easy way.

Related

MVC4 C# Project: Provide a single instance of an object across the application

Background
I am going to provide the background here before posing my actual question:
I am working on an ASP.NET MVC 4 project in C#. The current development task I am busy with is to implement RazorMachine (https://github.com/jlamfers/RazorMachine) in this web application in order to leverage the use of the Razor engine in my application layer (as opposed to purely in the MVC web layer). I have successfully implemented RazorMachine in a series of Test Fixtures and all is working great. Now, I need to implement it into my application architecture inside my application layer.
In his CodeProject article on RazorMachine (http://www.codeproject.com/Articles/423141/Razor-2-0-template-engine-supporting-layouts), Jaap Lamfers states "Please note that normally for performance reasons at any application you would create a singleton instance of RazorMachine (because of the inner instance bound JIT created type caching)".
A very basic example of the code in action is as follows:
RazorMachine rm = new RazorMachine();
ITemplate template = rm.ExecuteContent("Razor says: Hello #Model.FirstName #Model.LastName",
new {FirstName="John", LastName="Smith"});
Console.WriteLine(template.Result);
You can view more code samples on the CodeProject site.
With this as background, my question is as follows:
What is the best way to provide a single instance of the RazorMachine object to my MVC application?
Let me state that I am aware of the Singleton and Factory patterns and their possible implementations. However, using Singleton doesn't seem to sit right as I am not writing the class from scratch, the class already exists. Factory also seems to not be wholly appropriate, but I would like to hear what others say.
All input will be greatly appreciated.
THe quickest, easiest way to get a singleton instance of RazorMachine is to use your DI container of choice, examples of well known DI containers are Autofac, Ninject, Castle Windsor, Unity, StructureMap (see this link for a performance comparision of major .NET Ioc/DI containers: http://www.palmmedia.de/blog/2011/8/30/ioc-container-benchmark-performance-comparison)
These containers abstract away from you the developer the responsibility to correctly implementing the Singleton pattern.
Using Autofac, to register a singleton instance of a class you would do the following:
var builder = new ContainerBuilder();
builder.RegisterType<YourClassGoesHere>().SingleInstance();
Ref:http://autofac.readthedocs.org/en/latest/lifetime/instance-scope.html#single-instance

MVC 5 DI with Web API 2 DI--how should dependency registrations be structured?

I'm creating an MVC 5 site with Web API 2 functionality inside it as well and I'm wondering how I should work with the fact that ASP.NET uses 2 different resolver instances for resolving MVC controllers and ApiControllers.
I found this article that explains how to configure the resolution, but it looks like it uses 2 separate container instances and doesn't explain how to register dependencies for each. It's just like "do your registration here."
Following the 2-container example, I was tempted to set up the app so that the Web API container only has Web API dependencies and the MVC container only has mvc controller dependencies, but I feel like in the situation where a component is used for both, having a subset of items used in both containers would be too much work to maintain correctly.
Is it okay to just have all of the dependencies installed in each container? Or is it better to use the same container in each resolver?
Edit: I'm not using Unity so I'm writing a resolver class to wrap Windsor. I'm considering having my resolver implement both interfaces and just assigning the same instance as the different resolvers as well.

C# Windsor Castle with ASP.Net Web forms - How to Resolving Business Class Library

I'm starting to use the Windsor Castle IoC container. The web app is ASP.Net Web forms, and there is a class library of business objects that I'm trying to add DI to.
I am initializing the Windsor Container in the Global.asax Application_Start method. I really will only want the container to be used in the Business Class library. The Class library doesn't know about the web application. It's in a different project.
What is the preferred way to initialize and resolve objects in this scenario?
i don't think you should use a DI container in your BL. this is the whole point with DI. object composition can be done in a variety of ways and this is determined in the composition root of your application. your composition root is not in your BL therefore the BL should have no reference to Castle Windsor. your composition root (the place where the objects are actually composed, where dependencies are actually resolved) is your web application project. it is there that you should decide how to compose your object graph: use Windsor, another container or poor man's DI.
also, creating the composition root in a web forms app is a little tricky. you can read more about this in 'Dependency injection in .net' by Mark Seemann p224-p230

IoC Registration differences between Unity and Simple Injector

I have one project functioning perfectly using Unity. I try switching to use Simple Injector instead and now NO changes ever get saved in my database. I believe it has to do with the lifetime of the registered components. Here is the Unity container registration:
private IUnityContainer GetUnityContainer()
{
IUnityContainer container = new UnityContainer()
.RegisterType<IDatabaseFactory, DatabaseFactory>(
new HttpContextLifetimeManager<IDatabaseFactory>())
.RegisterType<IUnitOfWork, UnitOfWork>(
new HttpContextLifetimeManager<IUnitOfWork>())
.RegisterType<ICategoryRepository, CategoryRepository>(
new HttpContextLifetimeManager<ICategoryRepository>())
.RegisterType<ICategoryService, CategoryService>(
new HttpContextLifetimeManager<ICategoryService>());
return container;
}
And here is the new Simple Injector registration.
container.Register<IDatabaseFactory, DatabaseFactory>();
container.Register<IUnitOfWork, UnitOfWork>();
container.Register<ICategoryRepository, CategoryRepository>();
container.Register<ICategoryService, CategoryService>();
I'm not sure how the HttpContextLifetimeManager comes into play with Simple Injector. MVC is the client for the unity example, but I'm changing to a WPF project and Simple Injector. Any suggestions are much appreciated. Thanks.
#Steven. Thanks for your comment. I just discovered that since my RepositoryBase and my UnitOfWork inject an IDatabaseFactory in their constructors that I needed to use container.RegisterSingle<IDatabaseFactory, DatabaseFactory>(). This resolved one issue. I still have a problem with lifetime though. Since my consuming app is WPF, how will the RegisterPerWebRequest work?
My project has a DataLayer >> BusinessLayer >> WcfService >> WPF Front end. Simple Injector is set on the WcfService project and the business layer has Boostrapper to register items there. As of now, my WPF client will GetAllCountries() and display in a grid. If I change the name of one and try to update, I get the "An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key." error. I've done some debugging and find that after the GetCountries service call in the WPF client, when I go back to try to update, I see ALL of the countries are attached to the context via dbContext.ChangeTracker.Entries(). At this point I should have NO entities being tracked as my context should have been disposed after the first unit of work.
In an MVC app the RegisterPerWebRequest fixes that, but what is the equivalent for WPF? I'm going to install the extension now and try it anyway but I have a feeling it isn't the solution I'm looking for.. or is it? Thanks again for the help.
OK. I did a bit more digging and found a solution that works. I'm just not sure if it's the correct one. Anyway, now in my BLL where there is a bootstrapper to register things, I can register like this:
container.RegisterPerWcfOperation<IDatabaseFactory, DatabaseFactory>();
container.RegisterPerWcfOperation<IUnitOfWork, UnitOfWork>();
container.RegisterPerWcfOperation<ICountryRepository, CountryRepository>();
That gives me what I was looking for. Only a single instance of DatabaseFactory is ever created and thus my repository and unit of work share it like they should. Also, after GetCountries() on the client, when I do my second call to the service to perform and update, I check the dbContext.ChangeTracker.Entries() and see that there are NO entities being tracked, which is correct. I can now attach, set to modify, and call SaveChanges without getting the duplicate key error. Does this seem ok? Thanks.
The Register overloads over Simple Injector register types using the transient lifestyle (which means no caching). Every time you request an instance (or inject an instance) a new instance is created. In Unity this is the same; the default lifestyle is transient.
It seems that registering those types with a Per Web Request lifestyle is quite essential. It's not strange that changes are not committed to the database when the class that does those commits on an IUnitOfWork gets a different instance than the class who actually makes the changes to the IUnitOfWork.
Simple Injector's equivalent to Unity's HttpContextLifetimeManager is the WebRequestLifestyle. This lifestyle is not part of the core library, but is available as NuGet package.
After you included this in your project, you can do the following registration:
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
container.Register<IDatabaseFactory, DatabaseFactory>(Lifestyle.Scoped);
container.Register<IUnitOfWork, UnitOfWork>(Lifestyle.Scoped);
container.Register<ICategoryRepository, CategoryRepository>(Lifestyle.Scoped);
container.Register<ICategoryService, CategoryService>(Lifestyle.Scoped);
Or the equivalent:
Lifestyle lifestyle = new WebRequestLifestyle();
container.Register<IDatabaseFactory, DatabaseFactory>(lifestyle);
container.Register<IUnitOfWork, UnitOfWork>(lifestyle);
container.Register<ICategoryRepository, CategoryRepository>(lifestyle);
container.Register<ICategoryService, CategoryService>(lifestyle);
The default behavior of the WebRequestLifestyle is to dispose created instances when the web request ends. No special registration for this is required (Simple Injector hooks up an HttpModule for you when the application starts).
UPDATE:
My apologies for not reading your question to the last line. I missed the fact that you want to configure it using a WPF client.
As you probably know, since your client is a different application than the WCF service is, you'll have two Composition Roots in your system; one for the client, one for the service. Their registration will probably be quite different. Starting with Simple Injector v4.1, for a WCF service, you would indeed need a AsyncScopedLifestyle or when you follow the reference architecture at dotnetjunkie/solidservices, you'll find it as easy to use ThreadScopedLifestyle and define a scope explicitly in your two Execute methods.
I find managing the lifetime of objects in clients of two tier applications (client -> database) rather hard, since it is hard to define a unit of work for a certain scope. Since you are using the command/handler + query/handler approach, things will get so much easier. There won't be any unit of work on the client. Just on the server. Your presenter can just depend on several IQueryHandler<TQuery, TResult> and ICommandHandler<TCommand> interfaces and you're done. A query doesn't change state and a command should be an atomic operation. In other words, a unit of work is only needed within the boundary of an executing command.

Webforms and Dependency Injection

I am in the process of introducing a Dependency Injection framework into an existing WebForms application (using Castle Windsor).
I have pretty deep experience with DI, and tend to very strongly favor constructor injection over setter injection. If you are familiar with Webforms, you know that the ASP.Net framework handles the construction of page and control objects, making true constructor injection impossible.
My current solution is to register the container in the Application_Start event of the Global.asax, and keep the container as a public static variable in Global as well. I then simply resolve each service that I need directly in the page or control when I need them. So at the top of each page, I end up with code like this:
private readonly IMyService _exposureManager = Global.IoC.Resolve<IMyService>();
private readonly IMyOtherService _tenCustomersExposureManager = Global.IoC.Resolve<IMyOtherService>();
Obviously, I don't like having all these references to the container scattered about my application or having my page/control dependencies be non-explicit, but I have not been able to find a better way.
Is there a more elegant solution for using DI with Webforms?
I agree with #DarinDimitrov that MVP is an interesting option. However, when working with a legacy application, rewriting an existing page to the MVP pattern is a hell of a job. In that case it might be better to start with the Service Locator pattern (but only in your UI classes) as you are already doing. However, do change one thing. Do not expose the chosen DI container to the application, as I expect you are doing with the Global.IoC property.
Instead, create a static Resolve<T> method on the Global class. This hides the container completely and allows you to swap implementations without having to change anything in your web pages. When you do this, there is no advantage in using the Common Service Locator as #Wiktor proposes. The Common Service Locator is just another abstraction for something that doesn't have to be abstracted (since you've already abstracted away the container using the Global.Resolve<T>).
Unfortunately with Web forms, there is not really any good way to do this. For Simple Injector, I wrote an integration guide for Web Forms that basically describes the use of the Global.Resolve<T> method, but also shows a way to tests if Page classes can be created. The guide can be used for other DI containers as well.
BTW, please keep in mind that with Castle Windsor, everything you request must be released explicitly (the Register Resolve Release pattern). This is a bit nasty (IMO) and differs from how other containers work and can be a source of memory leaks when you do not do this correctly.
Last note. It is possible to do constructor injection with Web Forms. Well... sort of, since this will call the overloaded constructor using reflection after the Form has been created using the default constructor, so this causes Temporal Coupling.
Is there a more elegant solution for using DI with Webforms?
Yeap, the MVP pattern allows you to have a clean separation of concerns in a WebForms application. And once you have separation of concerns and weak coupling, DI is easy.
And in ASP.NET MVC that's built-in.
Know that this is pretty old, but now, there is DI in WebForms starting in .NET 4.7.2. Regarding to this article: ASP.NET Blog: Use Dependency Injection In WebForms Application
Just install Microsoft.AspNet.WebFormsDependencyInjection.Unity package and registr your classes in Global.asax:
protected void Application_Start(object sender, EventArgs e)
{
var container = this.AddUnity();
container.RegisterType<IPopularMovie, MovieManager>();
container.RegisterType<IMovieRepository, XmlMovieRepository>();
}
Hope it help.
ASP.NET MVC has IDependencyResolver and a static manager class that lets you get and set the resolver. I didn't like the idea of referencing System.Web.Mvc in a web forms project, so I went with IServiceLocator, which does about the same thing:
public static class Bootstrapper
{
private static readonly IUnityContainer _container = new UnityContainer();
public static void Initialize()
{
ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(_container));
_container.RegisterType<IDriverService, DriverService>();
}
public static void TearDown()
{
_container.Dispose();
}
}
public class Global : HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
Bootstrapper.Initialize();
}
protected void Application_End(object sender, EventArgs e)
{
Bootstrapper.TearDown();
}
}
Then in your Page class ...
IDriverService service = ServiceLocator.Current.GetInstance<IDriverService>();
Or wire up DI via constructor injection. I haven't gone down that road with web forms yet, so someone else will need to fill in for me :) (I've been living mostly in MVC land for about a year now).
My example uses Unity, but you should be able to adapt it to any other DI implementation fairly easily.
As #DarinDimitrov says the MVP pattern is the way to go in order to use DI/IOC with Webforms.
Either you can roll your own implementation or use an existing framework. I've heard good about Webforms MVP, but I haven't actually used it.
According to the docs, it has built in support for DI via Castle Windsor, Autofac and Unity. It also has convention based auto discovery for Presenters.
Actually, what you have just built is your own implementation of the Service Locator. But, almost for sure, an implementation already exists for a IoC framework of your choice.
http://commonservicelocator.codeplex.com/

Categories

Resources