When creating an application with Dependency Injection and it utilizes a framework for Dependency Injection such as Unity (or Ninject).
How do you initialize registering the interfaces to the container at the beginning all together and keep them available for the application to use throughout its running lifecycle of the application?
Do you need to pass the DI Container to each method that may utilize dependency injection, or is there some way to make the container globally accessible so that you can register them all together in the beginning and access them throughout running the application without having to continually pass them, and be able to utilize them when ever needed?
Environment: Visual Studio 2015, C#, Microsoft Unity (for DI Container)
Example Code
static void Main(string[] args)
{
// Make Unity resolve the interface, providing an instance
// of TrivialPursuit class
var diContainer = new UnityContainer();
diContainer.RegisterType<IGame, TrivialPursuit>();
var gameInstance = diContainer.Resolve<IGame>();
var xotherClass = new AnotherClass();
xotherClass.TestOtherClassOtherMethod();
}
------ Another class without context of the Dependency Injection Class ------
public void TestOtherClassOtherMethod()
{
IGame gameInstance = -- -Container is Not available to resolve from in this class ---
}
Reason: I don't want to need to pass every possible type that I may need later on to each class I load up, I will just want to use the instances when I need them. The more deeper I get into classes, later as the application becomes more complex, I won't want to pass down instances for each type up from the Main() method to each class.
A Dependency Injection (DI) container is just that. A framework for facilitating DI. You don't pass the container around in order to resolve instances of objects. You just request the type you need in your classes constructor and the DI framework will inject the appropriate dependency.
Mark Seemann has written a good book on dependency injection that I would recommend.
You register everything that'll need to be resolved with the container in the composition root. That is to say when your program starts up is when everything should be registered.
Let's say we have the following code:
public class MyClass
{
public Run()
{
var dependency = new Dependency1();
dependency.DoSomething();
}
}
public class Dependency1
{
public void DoSomething()
{
var dependency = new Dependency2();
dependeny.DoSomethingElse();
}
}
public class Dependency2
{
public void DoSomethingElse()
{
}
}
This gives us the above dependency chain: MyClass -> Dependency1 -> Dependency2.
The first thing we should do is refactor the classes to take their dependencies through their constructor and rely on interfaces rather than concretions. We can't inject dependencies unless there is a place to inject them (constructor, property, etc).
Here is the refactored code:
public interface IMyClass
{
void Run();
}
public interface IDependency1
{
void DoSomething();
}
public interface IDependency2
{
void DoSomethingElse();
}
public class MyClass : IMyClass
{
public readonly IDependency1 dep;
public MyClass(IDependency1 dep)
{
this.dep = dep;
}
public void Run()
{
this.dep.DoSomething();
}
}
public class Dependency1 : IDependency1
{
public readonly IDependency2 dep;
public MyClass(IDependency2 dep)
{
this.dep = dep;
}
public void DoSomething()
{
this.dep.DoSomethingElse();
}
}
public class Dependency2 : IDependency2
{
public void DoSomethingElse()
{
}
}
You'll notice the classes now all take their dependencies through their constructors and do not new up anything. Classes should only take in dependencies that they actually need. For example, MyClass does not NEED a Dependency2 so it doesn't ask for one. It only asks for a Dependency1 because that's all it needs. Dependency1 NEEDS Dependency2, not MyClass.
Now to wire it all up WITHOUT a container we would just new it all up in the composition root:
void Main()
{
var myClass = new MyClass(new Dependency1(new Dependency2()));
}
You can see how that could get cumbersom if we had tons of classes and depdencies. That's why we use a container. It handles all the depdency graph for us. With a container we'd rewrite it as follows:
void Main()
{
// the order of our registration does not matter.
var container = new Container();
container.Register<IDependency1>.For<Dependency1>();
container.Register<IDependency2>.For<Dependency2>();
container.Register<IMyClass>.For<MyClass>();
// then we request our first object like in the first example (MyClass);
var myClass = container.Resolve<IMyClass>();
myClass.Run();
}
In the second example the container will handle wiring up all the dependencies. So we never need to pass Depedency2 to MyClass and then to Depedency1. We only need to request it in Dependency1 and the container will wire it up for us like in the first example.
So in your example we would rewrite it like so:
static void Main(string[] args)
{
var game = new UnityContainer();
game.RegisterType<IGame, TrivialPursuit>();
game.RegisterType<IAnotherClass, AnotherClass>();
game.RegisterType<IYetAnotherClass, YetAnotherClass>();
var gameInstance = game.Resolve<IGame>();
// you'll need to perform some action on gameInstance now, like gameInstance.RunGame() or whatever.
}
public class Game : IGame
{
public Game(IAnotherClass anotherClass)
{
}
}
public class AnotherClass : IAnotherClass
{
public AnotherClass(IYetAnotherClass yetAnotherClass)
{
}
}
public class YetAnotherClass : IYetAnotherClass {}
In these cases there is no need to pass the container around. You register your dependencies with the container then request them in your classes constructors. If you wish to use the container in the class WITHOUT requesting it through the constructor then you are not doing DI you are just using the container as a singleton service locator. Something that should generally be avoided.
Container as a Service Locator
This should be generally avoided but if you want to use the container as a service locator you have two options:
1) Pass the container into your classes that need it through the constructor.
You can use the above examples for wiring your classes up for DI. But instead of requesting a dependency like IDependency in the constructor you just pass the container.
public class Game : IGame
{
public Game(IContainer container)
{
var blah = container.Resolve<IBlah>();
}
}
2) Request your container through a static class:
public static class ServiceLocator
{
private static IContainer container;
public static IContainer Container
{
get
{
if (container == null)
{
container = new Container();
}
return container;
}
}
}
Register everything as normal in your composition root using the ServiceLocator class. Then to use:
public class MyClass
{
public void DoSomething()
{
var blah = ServiceLocator.Container.Resolve<IBlah>();
}
}
Related
I'm working on a project which currently uses the Service Locator Anti-Pattern all over the code. I'm starting the process to slowly convert everything to using dependency injection, however because of the sheer size of the project I'd like to do this over the course of time.
I'm have a custom factory with 100's of dependencies registered with custom implementations. So I'd like to just wrap my container with unity, if my current container doesn't have the implementation then fall back to use unitys.
I've written this class to wrap IUnityContainer
public class GlobalFactoryUnityWrapper : IUnityContainer
{
IUnityContainer _unityContainer = new UnityContainer();
IUnityContainer _parent;
public GlobalFactoryUnityWrapper(IUnityContainer parent = null)
{
this._parent = parent ?? this._unityContainer.Parent;
}
public IUnityContainer Parent => this._parent;
//... Other IUnityContainer members
public object Resolve(Type type, string name, params ResolverOverride[] resolverOverrides)
{
if(GlobalContext.InstanceFactory.CanGetInstance(type))
{
return GlobalContext.InstanceFactory.GetInstance(type);
}
return this._unityContainer.Resolve(type, name, resolverOverrides);
}
}
I have most of the dependencies register for my controller there, However the controllers themselves are not, So it falls back to use unity's container.
Edit
I think I'm using the wrong thing, I should be using a strategy. my main goal is if the container doesn't contain an implementation, Fall back to use a what's registered in the old container
I needed to create a fallback strategy, this probably isn't the most optimal code but it's working for now
public class FactoryFallbackExtension : UnityContainerExtension
{
public FactoryFallbackExtension()
{
}
protected override void Initialize()
{
var strategy = new FallBackStrategy(Context);
Context.Strategies.Add(strategy, UnityBuildStage.PreCreation);
}
}
public class FallBackStrategy : BuilderStrategy
{
private ExtensionContext baseContext;
public FallBackStrategy(ExtensionContext baseContext)
{
this.baseContext = baseContext;
}
public override void PreBuildUp(IBuilderContext context)
{
var key = context.OriginalBuildKey;
if (key.Type.IsInterface)
{
if(GlobalContext.InstanceFactory.CanGetInstance(key.Type))
context.Existing = GlobalContext.InstanceFactory.GetInstance(key.Type);
}
}
}
Then When I configure my container I can just add the Container extension like so:
public static void Configure()
{
var container = new UnityContainer();
RegisterDepedencies(container);
container.AddExtension(new FactoryFallbackExtension());
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
SetControllerFactory(container);
}
So I have windsor set up and all of my services registered. I have a class that requires these services in the ctor, but this class isn't registered with windsor as it does not have an interface and I don't want to give it one for the sake of dependency resolution. What I'm really interested in, is having windsor resolve and inject my registered dependencies and hand me back an initialized class -- basically a factory.
The problem that I'm running into is that windsor throws because the dependent class has not been registered:
void Main()
{
var container = new WindsorContainer();
container.Register(Component
.For<ITestInterface>()
.ImplementedBy<TestImpl>()
.LifestyleTransient());
var c = container.Resolve<TestClass>(); // throws because TestClass isn't registered
c.Run();
}
public class TestClass
{
private ITestInterface _d;
public TestClass(ITestInterface d)
{
_d = d;
}
public void Run()
{
_d.Do();
}
}
public interface ITestInterface
{
void Do();
}
public class TestImpl : ITestInterface
{
public void Do()
{
Console.WriteLine("done");
}
}
What I don't want to end up doing, is something like this:
var dependency1 = container.Resolve<ITestInterface>();
var c = new TestClass(dependency1);
c.Run();
Because now we're in service locator territory. But more importantly, classes that have several dependencies...well that could get tedious.
How can I get windsor to have the desired factory effect? Or is this even possible with Windsor? I recall this being possble with Ninject.
So the popular response seems to be "Just register the component" which I really don't like at all because for such a simple use case, I could end up with a config class with hundreds of unnecessary registrations. That's kind of silly. So in the meanwhile, until I discover some built in functionality for this, I've create a cheesy extension that should land me somewhere in the middle. This extension simply takes the type, registers it for you and then tries to resolve it. That way, it's leveraging Windsor's own ctor resolution logic:
public static class WindsorExtentions
{
public static T Construct<T>(this IWindsorContainer container)
where T : class
{
if (!container.Kernel.HasComponent(typeof(T)))
container.Register(Component.For<T>());
var instance = container.Resolve<T>();
return instance;
}
}
What I would really like to do is register it, resolve it, then unregister it, but it appears that the RemoveComponent method has been removed in 3.0. This should be fine in the meanwhile. It obviously isn't all-inclusive with use cases, but when you have loads of proxy classes that have several required dependencies to be injected, I think this helps.
Usage:
var myClassWithDependencies = myContainer.Construct<MyClassWithDependencies>();
public class MyClassWithDependencies
{
public MyClassWithDependencies(
IFacebookClient facebookClient,
IGooglePlusClient googlePlusClient,
ITwitterClient twitterClient,
ISalesforceClient salesforceClient,
IReportRepository reportRepo,
IUserRepository userRepo)
{
}
}
I believe I understand enough about dependency injection to get started with it, but I'm having trouble understanding IOC containers vs service location, and how to construct my objects utilizing the container.
Given:
public interface IFooService
{
void DoSomethingFooey();
}
public class FooService : IFooService
{
readonly IBarService _barService;
public FooService(IBarService barService)
{
this._barService = barService;
}
public void DoSomethingFooey()
{
// some stuff
_barService.DoSomethingBarey();
}
}
public interface IBarService
{
void DoSomethingBarey();
}
public class BarService : IBarService
{
readonly IBazService _bazService;
public BarService(IBazService bazService)
{
this._bazService = bazService;
}
public void DoSomethingBarey()
{
// Some more stuff before doing ->
_bazService.DoSomethingBazey();
}
}
public interface IBazService
{
void DoSomethingBazey();
}
public class BazService : IBazService
{
public void DoSomethingBazey()
{
Console.WriteLine("Blah blah");
}
}
Without an IOC container I would have to provide all of my dependencies at construction like so:
public void DoStuff()
{
// Without a container, I would have to do something yucky like:
FooService fs = new FooService(
new BarService(
new BazService()
)
);
// or
BazService bazService = new BazService();
BarService barService = new BarService(bazService);
FooService fooService = new FooService(barService);
}
I am gaining seemingly a lot by constructing my classes in this DI manner, because I can now independently test my classes, when before using DI I really couldn't.
But with what I'm reading about the "proper way" of doing DI, I would use an IOC container like Unity or StructureMap... but I haven't found exactly what I need to understand how to get started.
I'm going to assume my container would look something like this:
var container = new Container(_ =>
{
_.For<IFooService>().Use<FooService>();
_.For<IBarService>().Use<BarService>();
_.For<IBazService>().Use<BazService>();
});
That was taken from the example at: http://structuremap.github.io/quickstart/
Based on the above example, I'm unsure of what the signature of the method containing var container... looks like, or how it is called and kept within scope. And perhaps more importantly how to actually construct the object utilizing the container.
What does my DoStuff() look like now if I wanted to create an instance of FooService (and in turn BarService and BazSerivce)?
Previously it was:
public void DoStuff()
{
// Without a container, I would have to do something yucky like:
FooService fs = new FooService(
new BarService(
new BazService()
)
);
// or...
}
But what does it look like now utilizing my container? And how does my method know where to look for my container?
Hopefully I'm somewhat on the right track, but please let me know if I'm not, and what I'm missing.
Your DoStuff method revised to use the container would look something like this:
public void DoStuff()
{
IFooService fooService = container.GetInstance<IFooService>();
// do something with fooService
}
I'm basing this off of the StructureMap link that you referenced. Other IoC containers name their equivalent "GetInstance" method differently.
You wouldn't normally create your container within the same method where you're trying to obtain an instance of IFooService though. Typically, you'd configure your container elsewhere in some initialization method and keep the container somewhere that you can access easily, such as in a static property. So, your DoStuff method might look more like this:
public void DoStuff()
{
IFooService fooService = MyIoCContainer.Current.Getinstance<IFooService>();
// do something with fooService
}
where MyIoCContainer is just a class that you've defined, and its Current property is the StructureMap container that you configured during initialization.
However, you're not always required to write code like this in order to obtain your services. Some frameworks provide hooks to make use of your IoC container so that you continue to use dependency injection all the way through your classes, and the framework takes care of instantiating your classes using your IoC container.
Just one example, the ASP.NET MVC framework provides an IDependencyResolver interface and DependencyResolver class that you can use to allow that framework to use your IoC container when instantiating your controller classes in your web application. That way, you can continue to use dependency injection all the way up into your controllers and therefore don't need to explicitly reference your IoC container within your controllers at all. See this section on "Including a Custom Dependency Resolver" for how that is accomplished.
So, ideally your DoStuff method and its containing class would look something like this, which is just a further continuation of dependency injection. The question then is how this MyStuffDoer class gets instantiated: either by a framework that understands how to use your IoC container to create it, or by you writing some explicit code somewhere to instantiate it from the IoC container.
class MyStuffDoer
{
IFooService fooService;
public MyStuffDoer(IFooService fooService)
{
this.fooService = fooService;
}
public void DoStuff()
{
// do something with fooService
}
}
I usually do this to keep DI and avoid drawbacks of IOC containers:
public interface IFooService
{
void DoSomethingFooey();
}
public class FooService : IFooService
{
readonly IBarService _barService;
public FooService() : this(new BarService()) {}
public FooService(IBarService barService)
{
this._barService = barService;
}
public void DoSomethingFooey()
{
// some stuff
_barService.DoSomethingBarey();
}
}
public interface IBarService
{
void DoSomethingBarey();
}
public class BarService : IBarService
{
readonly IBazService _bazService;
public BarService() : this(new BazService()) {}
public BarService(IBazService bazService)
{
this._bazService = bazService;
}
public void DoSomethingBarey()
{
// Some more stuff before doing ->
_bazService.DoSomethingBazey();
}
}
public interface IBazService
{
void DoSomethingBazey();
}
public class BazService : IBazService
{
public void DoSomethingBazey()
{
Console.WriteLine("Blah blah");
}
}
I need to get or access to my IoC container in a static class. This is my (simplified) scenario:
I register dependencies for ASP .net Web Api in a Startup class (but also I do this for MVC or WCF. I have a DependecyResolver project, but for simplicity, consider the following code)
// Web Api project - Startup.cs
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
var builder = new ContainerBuilder();
// ... Omited for clarity
builder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies())
.AsClosedTypesOf(typeof(IHandle<>))
.AsImplementedInterfaces();
// ...
IContainer container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
// ...
}
Then, in a separate class library I have my static class (again simplified for clarity):
public static class DomainEvents
{
private static IContainer Container { get; set; }
static DomainEvents()
{
//Container = I need get my Autofac container here
}
public static void Register<T>(Action<T> callback) where T : IDomainEvent { /* ... */ }
public static void ClearCallbacks() { /* ... */ }
public static void Raise<T>(T args) where T : IDomainEvent
{
foreach (var handler in Container.Resolve<IEnumerable<IHandle<T>>>())
{
handler.Handle(args);
}
// ...
}
}
Any idea how can I get this?
I need to get or access to my IoC container in a static class.
Any idea how can I get this?
Yes, you don't! Seriously. The pattern with the static DomainEvents class originates from Udi Dahan, but even Udi has admitted that this was a bad design. Static classes that require dependencies of their own are extremely painful to work with. They make the system hard to test and maintain.
Instead, create a IDomainEvents abstraction and inject an implementation of that abstraction into classes that require publishing events. This completely solves the your problem.
You can define your DomainEvents class as follows:
public interface IDomainEvents
{
void Raise<T>(T args) where T : IDomainEvent;
}
// NOTE: DomainEvents depends on Autofac and should therefore be placed INSIDE
// your Composition Root.
private class AutofacDomainEvents : IDomainEvents
{
private readonly IComponentContext context;
public AutofacDomainEvents(IComponentContext context) {
if (context == null) throw new ArgumentNullException("context");
this.context = context;
}
public void Raise<T>(T args) where T : IDomainEvent {
var handlers = this.context.Resolve<IEnumerable<IHandle<T>>>();
foreach (var handler in handlers) {
handler.Handle(args);
}
}
}
And you can register this class as follows:
IContainer container = null;
var builder = new ContainerBuilder();
builder.RegisterType<AutofacDomainEvents>().As<IDomainEvent>()
.InstancePerLifetimeScope();
// Other registrations here
container = builder.Build();
You can create a static method inside your DomainEvents class to inject the container like this:
public static class DomainEvents
{
public static void SetContainer(IContainer container)
{
Container = container;
}
....
}
And then from your ASP.NET application, call this method to inject the container:
DomainEvents.SetContainer(container);
Please note that I am giving you a direct answer to your question. However, here are some issues that I see with this:
Static classes should not be used when the class requires dependencies. In such case, refactor to use a non-static class and use Constructor Injection to inject the dependencies that you need in the class.
Using the container outside of the Composition Root is called Service Location and is considered an anti-pattern.
Class libraries should not use the container or even have a Composition Root. Quoting from the Composition Root article that I referenced:
Only applications should have Composition Roots. Libraries and frameworks shouldn't.
I want to inject Container property via SimpleInjector. I didn't find any functionality of SimpleInjector for that.
Then I wanted to register self container to itself, but Container has no interface.
I want this functionality because I don't to transfer Container object via constructor - because why if I can use auto inject of register objects.
My usage idea:
var container = new Container();
container.Options.AutowirePropertiesWithAttribute<InjectableProperty>();
container.Register<ISomething, Something>(Lifestyle.Singleton);
ISomething:
public interface ISomething
{
void SomeMethod();
}
Something class:
public class Something : ISomething
{
public void SomeMethod()
{
var environment = _container.GetInstance<IEnvironment>();
environment.DoSomething();
}
[InjectableProperty] // - maybe it is not possible (I don't know it)
Container Container {get;set;}
}
Do you have any idea to achieve that?
Thank you very much.
Prevent having your application code depend upon the container. The only place in your application that should know about the existence of your DI library is the Composition Root (the place where you register all your dependencies).
Instead of letting each class call back into the container (which is called the Service Locator anti-pattern), prefer using Dependency Injection. With Dependency Injection you inject dependencies instead of asking for them.
So you can rewrite your class to the following:
public class Something : ISomething
{
private readonly IEnvironment environment;
public Something (IEnvironment environment)
{
this.environment = environment;
}
public void SomeMethod()
{
this.environment.DoSomething();
}
}
Also, prevent doing any logic in your constructors besides storing the incoming dependencies. This allows you to compose object graphs with confidence.
In some cases however, it can still be useful to inject the Container into another class. For instance when creating a factory class that is located inside the Composition Root. In that case you can still use constructor injection, like this:
// Defined in an application layer
public interface IMyFactory
{
IMyService CreateService();
}
// Defined inside the Composition Root
public class MyFactory : IMyFactory
{
private readonly Container container;
public MyFactory(Containter container)
{
this.container = container;
}
public IMyService CreateService(ServiceType type)
{
return type == ServiceType.A
? this.container.GetInstance<MyServiceA>()
: this.container.GetInstance<MyServiceB>();
}
}
If Simple Injector detects a Container constructor argument, it will inject itself into the constructor automatically.