Dependency Injection when using static classes - dependency-injection

The general question - I know that static classes should be avoided when using DI Containers, but in a project I am working on, one of the static classes is a constraint that I can not avoid. I am adding a method to that static class and I need to be able to inject a service that was created by a DI container. One approach was to add a static access to the container, but I feel that this is an anti pattern. I wanted to know if there is a more elegant way to inject a service into a static method.
The Specific question - I am developing a WPF attached property, and in the change callback I need to get an instance of a service that was registered using a Unity DI Container. The only solution I could think of was to add a static property to the bootstrapper, that would return the Unity Container.
public class Bootstrapper
{
public static UnityContainer Instance
{
get
{
return _container;
}
}
But it feels wrong to store the container in a static field.
Are there other - more elegant - solutions?

Related

Where Do I Declare Unity Container?

I'm just getting started with Unity, and I'm having trouble finding any advice about where to declare my UnityContainer object. Most of the examples that I've seen consist of just a single method where the UnityContainer object is declared at the top, then its mappings are defined, then a few object types are resolved. But how do you handle the container when you need to access it in several places throughout the program? For example, the user clicks on a button which opens a new window and that window needs a controller, which itself needs to resolve several services? I also want some of the services that Unity manages to be singletons, so wouldn't that mean that I'd have to have only a single instance of my UnityContainer throughout my program to manage those singletons?
My first thought is to have my main Program class have a static UnityContainer property or expose some sort of UnityContainerFactory class which manages a singleton UnityContainer instance, but both of those methods seem bad because they create a global property which a lot of things are dependent on.
What's the accepted way of doing this?
As noted in the other answer, you should compose the entire object graph in the Composition Root.
Don't declare the container as a static field since this would encourage developers to use it as a service locator which is an anti-pattern.
How to solve your problem?
Use Dependency Injection.
Here is an example for your special WinForms case:
In your Program.Main method, create the container, register the service (the dependency that you need to use from the other window) and then resolve the main form and run it like this:
UnityContainer container = new UnityContainer();
container.RegisterType<IService, Service>();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(container.Resolve<MainForm>());
In the MainForm, declare a dependency on a Func<SecondForm> where SecondForm is the form that you need to create from the main form when the button is clicked. Consider the following code inside your main form file:
public partial class MainForm : Form
{
private readonly Func<SecondForm> m_SecondFormFactory;
public MainForm(Func<SecondForm> second_form_factory)
{
m_SecondFormFactory = second_form_factory;
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
SecondForm second_form = m_SecondFormFactory();
second_form.Show();
}
}
Please note that Func<SecondForm> acts as some kind of factory. I use it in this case because unity has a feature to support late construction of dependencies via Func.
The SecondForm has a dependency on IService like this:
public partial class SecondForm : Form
{
private readonly IService m_Service;
public SecondForm(IService service)
{
m_Service = sevice;
InitializeComponent();
}
//Use service here
}
You can now use IService from the second form.
Using Seemann words:
As close as possible to the application's entry point.
Give a look at http://blog.ploeh.dk/2011/07/28/CompositionRoot/ from the great Seemann.
I think that is totally acceptable for the main container to be a static field that get disposed together with your application, just remember to don't tie your classes to your container.
Get noticed of the so called "Service Locator" (again from Seemann: http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/)
Where to declare it really depends on the application, I'd go for the startup class of an owin application or the Main method of a console/WPF app.

MVC Single Instance Object

I need to declare an object in MVC app. This object consume memory so I need it to be created once when app start and won't be destroy until recycled. The same instance of the object also should be able accessed across application within controllers.
I have used this object in WCF service by using InstanceContextMode.Single and works great. But how with MVC?
I would implement a Singleton Pattern https://msdn.microsoft.com/en-us/library/ff650316.aspx
If you are using any Dependency injection container then all of them have support for Singleton Instance
As singletons are largely considered an anti-pattern. They make your code hard to test (using mocks and stubs) and create tightly coupled code.
Since this is very bad practice, you are better off using an IoC container (Unity, SimpleIoC, Autofac, etc.) to manage the lifetime of your containers. The Unity 3 IoC container has an ContainerControlledLifetimeManager lifetime manager where objects are created once and the same instance is returned for the lifetime of the container.
In your composition root you could either do (using IMemoryConsumingService interface to avoid tight coupling). Then just inject it into your controllers and services. Example for Unity 3 (other IoC have similar procedure).
MemoryConsumingService service = new MemoryConsumingService();
container.RegisterInstance<IMemoryConsumingService>(service);
or
container.RegisterType<IMemoryConsumingService, MemoryConsumingService(new ContainerControlledLifetimeManager());
Edit:
When you install Unity 3.5 + Unity MVC Bootstraper you are basically ready to go for it.
public class UnityConfig
{
private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
public static IUnityContainer GetConfiguredContainer()
{
return container.Value;
}
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<IDriver, Driver>(new ContainerControlledLifetimeManager());
// OR
IDriver driver = new Driver();
container.RegisterInstance<IDriver>(driver);
}
}
Inside the RegisterType method you do your registration (please check out the documentation link below, IoC is to complicated to explain it within an simple answer). The newer nugetpackages get you ready to go, without any further changes (except adding registrations). No need to change the Global.asax as it was required in the early years of Unity.

how to use unit of work pattern in public static

I am Use this code For select 4 Last Record Of Database in various page
public static List<Tour> GetLastTour()
{
using (var Context = new MvcHghDbContext())
{
return (Context.Tours.Take(4).OrderByDescending(x=>x.Titl e).ToList());
}
}
How To Use unit of work pattern in static Method in Static Class ?
But Static Constructor Erorr!
such this code
plz help me:
public static class DropDownList{
private readonly ICatHotellService _catHotellService;
private readonly ICatTourismService _catTourismService;
private readonly ICatTourService _catTourService;
private readonly IUnitOfWork _uow;
public DropDownList(ICatHotellService CatHotellService, IUnitOfWork ouw, ICatTourService CatTourService, ICatTourismService CatTourismService)
{
_uow=ouw;
_catHotellService = CatHotellService;
_catTourismService = CatTourismService;
_catTourService = CatTourService;`
}
}
The short answer is that this can't work. Static classes may only have static constructors, and these get called by the runtime when the app is created. Thus, this happens long before your dependency injection has been configured. On top of that, you should never ever ever have static data contexts in a web application, because these are shared by all users of your app, thus two users using the same data context will write over each others data model.
You are not using UoW at all. UoW means injecting one instance of the MvcHghDbContext to different classes of your service layer during a request call and not instantiating it directly each time such as your GetLastTour method.
Don't use static classes in your service layer. extract an interface from them and let the IoC container manage its life time.
Also you can use service locator pattern (such as calling ObjectFactory.GetInstance<>) every where even in static classes. It's an anti pattern and should be avoided as much as possible, because now the IoC Container is a dependency in your class.

Where's Simple Injector's equivalent of StructureMap's ObjectFactory

I am in the process of migrating from StructureMap to Simple Injector in a ASP.NET MVC3 application.
I am using the MVC3 extension for controller DI, but I am running into an issue with trying to replace the static aspects of StructureMap. We have calls to
StructureMap.ObjectFactory.GetInstance<Interface>()
throughout different layers of the app. It does not look like Simple Injector has a way to do that.
Am I missing something? Or is Simple Injector not applicable for my application?
Please advise and thanks in advance.
Allowing the application to directly access the container is considered to be bad practice. It is an form of the Service Locator anti-pattern.
Because this is considered to be a bad thing, Simple Injector does not contain anything like StructureMap's ObjectFactory.GetInstance. And as a matter of fact, the author of StructureMap is considering the removal of the ObjectFactory API in a furure release of StructureMap.
However, nothing stops you from storing the SimpleInjector.Container instance in a static field and let the application use this:
// Service Locator implementation in low application layer.
public static class ObjectFactory
{
private static SimpleInjector.Container container;
public static void SetContainer(Container container)
{
ObjectFactory.container = container;
}
public static T GetInstance<T>() where T : class
{
return container.GetInstance<T>();
}
}
In Composition root:
public static void Initialize()
{
var container = new Container();
InitializeContainer(container);
DependencyResolver.SetResolver(
new SimpleInjectorDependencyResolver(container));
// Set the service locator here
ObjectFactory.SetContainer(container);
}
So there is no limitation in the Simple Injector that prevents you from doing this, but frankly, you are already witnessing one of the reasons why Service Locator is a bad thing: you switched containers and now you have to change application code.
Perhaps for now it is easiest for you to save the container in a static field (as shown in the example above), but please take the time to understand why this pattern is bad, and do refactor away from this pattern towards dependency injection (and especially constructor injection).

Inject VM to custom control in WPF using Unity

I am building a WPF based application. I am using Unity to inject all the different dependencies in my application (defined in App.xaml.cs).
In my MainApplication window I have a pretty complex look-less custom control derived from Control(is has about ten more control integrated in it).
I would like to inject a VM into this custom control without coupling it to any other object in my application (except App.xaml.cs of course)
Injection to any WPF window in my application works well, but when I try injecting to the custom control I am facing to different situation:
1. In case I am using
container.RegisterInstance(container.Resolve);
The DI creates a dummy instance of MyCustomControl and injects the VM (using [Dependency] attribute). However this specific instance is not used when I use it in my XAML:
in which case it initializes a new MyCustomControl ignoring any dependencies.
In case I am using
container.RegisterType();
The MyCustomControl completely ignores the injection.
I realize I am probably doing something wrong (not just technically) and I am really trying to avoid coupling this control (which will obviously solve the issue).
I don't know if this is the best solution and found your question while looking for other options but, alas, here is the approach I used to at least get up and running.
I created a base UnityControl class that subclasses Control. In the constructor, I use the ServiceLocator to get a reference to the container. Then I call the BuildUp method to resolve any dependencies on the derived control class. Any dependencies are implemented as read/write properties marked with the DependencyAttribute.
Here's what UnityControl looks like:
public abstract class UnityControl : Control
{
protected UnityControl() : base()
{
Container = ServiceLocator.Current.GetInstance<IUnityContainer>();
Container.BuildUp(this.GetType(), this);
}
protected IUnityContainer Container { get; private set; }
}

Resources