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.
Related
I have installed the Microsoft Dependency Injection into a .NET Framework 4.8 class library. I have also reigster interface A to class A. The problem is that my class B that takes a object of interface A in construtor still demands it when I try to create the class? So how do I get the DI system to provide this object in a class Library where there is no real entry point?
public Class B
{
B(){InterfaceA}
}
public Class A : InterfaceA
{}
public MainClass
{
public void DoStuff()
{
DependencyContainer.Register();
var myB = new B();
}
}
public DependencyContainer
{
public void Register()
{
(new ServiceCollection()).AddTransient<InterfaceA, A>();
}
}
Regards
DI means that any depencencies will come (get injected) from the outside. The class itself won't even know that dependency injection is used. In your case, the classes should be rewritten to accept dependencies instead of creating them:
public Class B
{
public A MyA {get;}
public B(InterfaceA a)
{
MyA=a;
}
}
public Class A : InterfaceA
{}
public MainClass
{
public B MyB {get;}
public MainClass(B b)
{
MyB=b;
}
public void DoStuff()
{
MyB......;
}
}
The classes know nothing about DI. When asked for a MainClass instance with, eg services.GetRequiredService<MyClass>(), the DI container will create all the necessary instances and pass them to the classes.
The common pattern for all .NET Core libraries is to provide extension methods that can be used to register or configure their classes in the main application's Startup class or ConfigureServices delegate. To do that, all that's needed is the IServicesCollection interface from the Microsoft.Extensions.DependencyInjection.Abstractions package. There's no need to add the full DI package :
public static class MyLibServiceExtensions
{
public static IServicesCollection AddMyClasses(this IServicesCollection services)
{
services.AddTransient<ClassB>()
.AddTransient<InterfaceA,ClassA>()
.AddTransient<MainClass>();
return services;
}
}
This can be used now to register the classes, eg in a Console application :
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddMyClasses()
.AddHostedService<Worker>();
});
}
Or the Startup.ConfigureServices method of a web app:
public class Startup
{
public Startup(IWebHostEnvironment env)
{
HostingEnvironment = env;
}
public IWebHostEnvironment HostingEnvironment { get; }
public void ConfigureServices(IServiceCollection services)
{
...
services.AddMyClasses();
}
}
The classes will now be injected into any class generated by the DI container, eg a `Controller:
public class MyController:ControllerBase
{
public MyController(MyDbContext dbContext,MainClass main)
{
_db=dbContext;
_main=main;
}
}
OK, so dependency injection isn't magic. Your Register method is building a collection of services and throwing it away. You need to actually resolve your components from the container (I'm not saying directly, but the container has to be involved).
You should build an IServiceProvider from it using the BuildServiceProvider method:
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient<InterfaceA, A>();
serviceCollection.AddTransient<B>();
var serviceProvider = serviceCollection.BuildServiceProvider();
var b = serviceProvider.GetRequiredService<B>(); // constructs B and injects A
Probably you should do this in your Main method, and then inject B (or a Func to create B) into MainClass:
static void Main(string[] args)
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient<MainClass>();
serviceCollection.AddTransient<InterfaceA, A>();
serviceCollection.AddTransient<B>();
serviceCollection.AddTransient<Func<B>>(provider => () => provider.GetRequiredService<B>()); // factory method
var serviceProvider = serviceCollection.BuildServiceProvider();
// ask the container for MainClass and then call DoStuff
var mainClass = serviceProvider.GetRequiredService<MainClass>();
mainClass.DoStuff();
}
And then you could rewrite MainClass like this:
public class MainClass
{
private readonly B _bInstance;
private readonly Func<B> _bFactory = new Func<B>();
// if you want to create instances of B as and when, I'd suggest using a factory
// otherwise you can pass in a single instance
// I've done both here as an example
public MainClass(Func<B> bFactory, B bInstance)
{
_bInstance = bInstance;
_bFactory = bFactory;
}
public void DoStuff()
{
// create two instances of B
var b1 = _bFactory();
var b2 = _bFactory();
}
}
While I advocate for using a factory when you need to build instances on the fly, it is possible to inject IServiceProvider itself into your classes, and then call its GetRequiredService or GetService methods. The reason I don't do this is because it is considered to be an anti-pattern. Using a factory allows you to still make changes at the composition root (i.e. in Main) without editing everywhere that creates instances of B.
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);
}
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>();
}
}
I know ASP.NET MVC has DependencyResolver. How to have the similar application-wide access to IUnityContainer in non-MVC applications? Using public static class is nonsense. Here is my use case:
public partial class App : Application
{
public App()
{
IUnityContainer container = new UnityContainer();
container.RegisterInstance(new MyClass());
}
}
public class MainViewModel
{
public MainViewModel()
{
IUnityContainer container = ???
if (container.IsRegistered<MyClass>())
DoSomething();
}
}
If you're looking for a solution that works for most applications you can register the component at the highest level, and then resolve it. As long as you resolve the instance Unity will resolve the dependencies (such as IUnityContainer).
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Registering dependencies ...");
var container = new UnityContainer();
container.RegisterType<ProgramStarter, ProgramStarter>();
// Do other registrations.
var program = container.Resolve<ProgramStarter>();
// Since ProgramStarter was resolved using Unity it will also resolve the container.
program.Run();
}
}
public class ProgramStarter
{
public ProgramStarter(IUnityContainer container)
{
// Do something with container.
}
public Run()
{
// Do stuff.
}
}
Or an example for WPF:
IUnityContainer container = new UnityContainer();
// Do registrations.
var window = container.Resolve<MainWindow>();
window.Show();
MainWindow will now be able to resolve both the container and other dependencies.
Also, have a look at this question: Where to place and configure IoC container in a WPF application?
As a sidenote I usually keep my container as a static instance, and seen a lot of other implementations doing the same thing. I find it convenient to be able to use it when you find yourself in a situation when it's not possible to resolve it.
public static class IocContainer
{
private static readonly Lazy<IUnityContainer> Container = new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
// Possibly do registrations here as well...
return container;
});
public static IUnityContainer Instance
{
get { return Container.Value; }
}
}
I don't think there is any way other than you specified to implement IOC and DI for non MVC applications. Still if there's a way then any suggestions are appreciated.
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");
}
}