Unity Extending Dependency Injection Containers - c#

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);
}

Related

dependency injection or factory pattern c#

I have to write a Complex calculator logic which has 4 different components to be calculated brokerage, stockprice, admin charges & other charges. Each having a different logic and formulas.
So I decided to use Unity DI. I have a ContainerFactoryClass which resolves all classes which implements IChargeCalculator interface as shown below in the TotalAnnualCostCalculator constructor.
public class TotalAnnualCostCalculator
{
private readonly IUnityContainer container;
//Constructor
public TotalAnnualCostCalculator()
{
container = ContainerFactory.InitializeContainer();
ContainerFactory.SetupContainer(container);
}
public AnnualCostCharges CalculateTotalAnnualCost(Parameters product)
{
var calculators = container.ResolveAll<ICalculator>().ToList();
// Invoke calcualtion method
Parallel.ForEach(calculators, c =>
{
return c.CalculateAnnualCost(product);
});
}
}
Container Factory class:-
public static class ContainerFactory
{
public static IUnityContainer Container { get; private set; }
public static IUnityContainer InitializeContainer()
{
var container = new UnityContainer();
RegisterDependencies(container);
return container;
}
private static void RegisterDependencies(UnityContainer container)
{
container.RegisterType<ICalculatorStrategyFactory, CalculatorStrategyFactory>("Factory");
container.RegisterType<IEffectiveAnnualCostCalculator, InvestmentManagementChargeCalculator>("IMCChargeCalculator",
new InjectionConstructor(new ResolvedParameter<ICalculatorStrategyFactory>("Factory")));
//container.RegisterType<IEffectiveAnnualCostCalculator, AdministrationChargeCalculator>("AdministrationChargeCalculator");
container.RegisterType<IEffectiveAnnualCostCalculator, AdviceChargeCalculator>("AdviceChargeCalculator");
container.RegisterType<IEffectiveAnnualCostCalculator, OtherChargeCalculator>("OtherChargeCalculator");
container.RegisterType<IInvestmentManagementChargeCalculator, LumpSumIMCCalculator>("LumpSumIMCCalculator");
container.RegisterType<IInvestmentManagementChargeCalculator, DebitOrderIMCCalculator>("DebitOrderIMCCalculator");
}
public static void SetupContainer(IUnityContainer container)
{
Container = container;
}
}
Then any API consumes my Calculator.dll by just creating an instance of TotalAnnualCostCalculator and call a method like this.
var totalCharges = calc.CalculateTotalAnnualCost(prod);
My code reviewer says its better to use Factory Pattern ,as this tightly coupled to Unity Framework.
Please advise
Indeed, don't use a DI Container at all. As Steven suggests in the comments, this seems a great fit for a Composite:
public class TotalAnnualCostCalculator : ICalculator
{
private readonly ICalculator[] calculators;
public TotalAnnualCostCalculator(params ICalculator[] calculators)
{
this.calculators = calculators;
}
public AnnualCostCharges CalculateTotalAnnualCost(Parameters product)
{
Parallel.ForEach(this.calculators, c => c.CalculateAnnualCost(product));
}
}
In the Composition Root, then, you simply new up all the ICalculator objects you'd like to use, and pass them to the constructor of TotalAnnualCostCalculator.
Register all IEffectiveAnnualCostCalculator (or what ever interface).
You just need to map the enumerable to an array of the same type.
container.RegisterType<IEnumerable<IEffectiveAnnualCostCalculator>, IEffectiveAnnualCostCalculator[]>();
Resolve with dependency injection:
private IEnumerable<IEffectiveAnnualCostCalculator> calculators;
public TotalAnnualCostCalculator(IEnumerable<IEffectiveAnnualCostCalculator> calculators)
{
this.calculators = calculators;
}
public AnnualCostCharges CalculateTotalAnnualCost(Parameters product)
{
Parallel.ForEach(this.calculators, c => c.CalculateAnnualCost(product));
}

Dependency Injection Container - How to keep available to

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>();
}
}

How to access IUnityContainer in non-MVC applications?

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.

Access or get Autofac Container inside a static class

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.

How to update Caliburn's SimpleContainer IoC registrations at runtime

I've registered an instance of a service in Caliburn's BootStrapper's Configure() method and it injects properly.
public class AppBootstrapper : BootstrapperBase
{
private SimpleContainer _container;
// ...
// other overridden functions
// ...
protected override void Configure()
{
_container = new SimpleContainer();
// ...
// window manager, event aggregator etc..
// ...
if (_runInDemoMode)
{
// run in demo mode against a mock service
_container.Instance<IMyService>(new MyServiceMock());
}
else
{
// run with the real service implementation
_container.Instance<IMyService>(new MyService());
}
}
}
I would like to be able to update the dependency rule registration from within a ViewModel at runtime so that a user can swap between a real implementation of my service and a mock implementation without having to restart the application.
E.g.
public class SettingsViewModel : PropertyChangedBase
{
// ...
// code
// ...
public void ChangeToDemoMode()
{
var container = IoC.GetContainer(); // <-- I made this up, how to do this?
container.UnregisterHandler(typeof(MyService), key?); // <-- I don't know what the key would be
container.Instance<IMyService>(new ServiceMock());
}
}
As you can see I don't know how to get a reference to the container in order to fiddle with it, and I also don't know how to unregister the existing registration after I do reference the container. Is there a way to do this or will it tear the fabric of the IoC continuum?
The way I did it was to create a class with dependency on SimpleContainer this gives
public class CaliburnRegistrationService : IRegistrationService
{
SimpleContainer _container;
public CaliburnRegistrationService(SimpleContainer simpleContainer)
{
_container = simpleContainer;
}
public void Register(IResolver resolver)
{
// register you stuff based on interface implementation
}
}
Then create IResolver implementations for each Mode of operation in your code e.g.DemoResolver and RealResolver
Then in Bootstrapper's Configure() do
_container.Singleton<IRegistrationService, CaliburnRegistrationService>();
_container.Singleton<IResolver, DemoResolver>(); // just some class that inherits from IResolver
_container.Singleton<IResolver, RealResolver>(); // just some class that inherits from IResolver
The by making the ViewModel dependent on IRegistrationService, it will allow you to call Register from the ViewModel.
And based on some parameters you can register your ioc container
public class SettingsViewModel : PropertyChangedBase
{
IRegistrationService _registrationService;
IEnumerable<IResolver> _resolver;
public MyViewModel(IRegistrationService registrationService, IEnumerable<IResolver> resolver)
{
_registrationService = registrationService;
_resolver = resolver;
}
public void ChangeToMode()
{
foreach(var resl in _resolver)
{
if(resl.ShouldRegister(.. some parameter..))
{
_registrationService.Register(resl);
return;
}
}
}
}
This gives you access to your IoC container anywhere

Categories

Resources