Avoiding container.Resolve in simple factory? - c#

New to Unity & DI. I was passing the container into my view model & calling .Resolve when I wanted a new view instance which I now know is bad practice.
I'm now resolving the view via a simple factory class which is passed into the view Model constructor as an Interface:
this.dialogView = this.dialogViewFactory.CreateDialogView();
I'm invoking RegisterType in Unity which resolves the view & viewModel:
this.unityContainer.RegisterType(typeof(IDialogView), typeof(DialogView));
this.unityContainer.RegisterType(typeof(IDialogViewModel), typeof(DialogViewModel));
this.unityContainer.RegisterType(typeof (IDialogViewFactory), typeof (DialogViewFactory));
Finally, my factory class. I am currently passing in the container & calling resolve here. I'm aware that although I've moved the dependency out of the view model I still have the container dependency in the factory class:
public class DialogFactory : IDialogFactory
{
private IUnityContainer unityContainer;
public DialogFactory(IUnityContainer unityContainer)
{
this.unityContainer = unityContainer;
}
public IDialogView CreateDialogView()
{
return this.unityContainer.Resolve<IDialogView>();
}
}
What is the best solution to this?

You could use Unity's Automatic Factories to eliminate the need for the factory by injecting a Func<IDialogView>:
public class ViewModel
{
private Func<IDialogView> dialogViewFactory;
public ViewModel(Func<IDialogView> dialogViewFactory)
{
this.dialogViewFactory = dialogViewFactory;
}
private IDialogView CreateDialogView()
{
return this.dialogViewFactory();
}
}
You could also use this approach to inject into the DialogFactory itself if you want/need a formal factory:
public class DialogFactory : IDialogFactory
{
private Func<IDialogView> dialogViewFactory;
public DialogFactory(Func<IDialogView> dialogViewFactory)
{
this.dialogViewFactory = dialogViewFactory;
}
public IDialogView CreateDialogView()
{
return this.dialogViewFactory();
}
}

Related

Working with Abstract Factory that is injected through DI container

I`m confused about Dependency Injection implementation in one concrete example.
Let's say we have a SomeClass class that has a dependency of type IClassX.
public class SomeClass
{
public SomeClass(IClassX dependency){...}
}
Creation of concrete implementations of IClassX interface depends on runtime parameter N.
With given constructor, I can't configure DI container(Unity is used), because I don't know what implementation of IClassX will be used in runtime.
Mark Seemann in his book Dependency Injection In .Net suggests that we should use Abstract Factory as an injection parameter.
Now we have SomeAbstractFactory that returns implementations of IClassX based on runtime paramater runTimeParam.
public class SomeAbstractFactory
{
public SomeAbstractFactory(){ }
public IClassX GetStrategyFor(int runTimeParam)
{
switch(runTimeParam)
{
case 1: return new ClassX1();
case 2: return new ClassX2();
default : return new ClassDefault();
}
}
}
SomeClass now accepts ISomeAbstractFactory as an injection parameter:
public class SomeClass
{
public SomeClass(ISomeAbstractFactory someAbstractfactory){...}
}
And that's fine. We have only one composition root where we create the object graph. We configure Unity container to inject SomeAbstractFactory to SomeClass.
But, let's assume that classes ClassX1 and ClassX2 have their own dependencies:
public class ClassX1 : IClassX
{
public ClassX1(IClassA, IClassB) {...}
}
public class ClassX2 : IClassX
{
public ClassX2(IClassA, IClassC, IClassD) {...}
}
How to resolve IClassA, IClassB, IClassC and IClassD dependencies?
1. Injection through SomeAbstractFactory constructor
We can inject concrete implementations of IClassA, IClassB, IClassC and IClassD to SomeAbstractFactory like this:
public class SomeAbstractFactory
{
public SomeAbstractFactory(IClassA classA, IClassB classB, IClassC classC, IClassD classD)
{...}
...
}
Unity container would be used in the initial composition root and then use poor man’s DI to return concrete ClassX1 or ClassX2 based on parameter runTimeParam
public class SomeAbstractFactory
{
public SomeAbstractFactory(IClassA classA, IClassB classB, IClassC classC, IClassD classD){...}
public IClassX GetStrategyFor(int runTimeParam)
{
switch(runTimeParam)
{
case 1: return new ClassX1(classA, classB);
case 2: return new ClassX2(classA, classC, classD);
default : return new ClassDefault();
}
}
}
Problems with this approach:
SomeAbstractFactory knows about dependencies that don`t really belong to it.
Deeper object graph would require to change both SomeAbstractFactory constructor and class implementation
DI container would not be used to resolve dependencies, poor man`s DI must be used
2. Explicit call to DI container
Instead of “newing up” ClassX1 or ClassX2, we would resolve them by using a DI container.
public class SomeAbstractFactory
{
public SomeAbstractFactory(IUnityContainer container){...}
public IClassX GetStrategyFor(int runTimeParam)
{
switch(runTimeParam)
{
case 1: return container.Resolve<IClassX>("x1");
case 2: return container.Resolve<IClassX>("x2");
default : return container.Resolve<IClassX>("xdefault");
}
}
}
Problems with this approach:
DI container is passed into SomeAbstractFactory
DI Resolve method is not used only at the composition root (ServiceLocator anti-pattern)
Is there another more suitable approach?
The example below shows how to do this with Unity. This blog post explains it a little better using Windsor. The underlying concept is exactly the same for each, just slightly different implementation.
I would rather allow my abstract factory to access the container. I view the abstract factory as a way to prevent dependency on the container - my class only depends on IFactory, so it's only the implementation of the factory that uses the container. Castle Windsor goes a step further - you define the interface for the factory but Windsor provides the actual implementation. But it's a good sign that the same approach works in both cases and you don't have to change the factory interface.
In the approach below, what's necessary is that the class depending on the factory passes some argument that allows the factory to determine which instance to create. The factory is going to convert that to a string, and the container will match it with a named instance. This approach works with both Unity and Windsor.
Doing it this way the class depending on IFactory doesn't know that the factory is using a string value to find the correct type. In the Windsor example a class passes an Address object to the factory, and the factory uses that object to determine which address validator to use based on the address's country. No other class but the factory "knows" how the correct type is selected. That means that if you switch to a different container the only thing you have to change is the implementation of IFactory. Nothing that depends on IFactory has to change.
Here's sample code using Unity:
public interface IThingINeed
{}
public class ThingA : IThingINeed { }
public class ThingB : IThingINeed { }
public class ThingC : IThingINeed { }
public interface IThingINeedFactory
{
IThingINeed Create(ThingTypes thingType);
void Release(IThingINeed created);
}
public class ThingINeedFactory : IThingINeedFactory
{
private readonly IUnityContainer _container;
public ThingINeedFactory(IUnityContainer container)
{
_container = container;
}
public IThingINeed Create(ThingTypes thingType)
{
string dependencyName = "Thing" + thingType;
if(_container.IsRegistered<IThingINeed>(dependencyName))
{
return _container.Resolve<IThingINeed>(dependencyName);
}
return _container.Resolve<IThingINeed>();
}
public void Release(IThingINeed created)
{
_container.Teardown(created);
}
}
public class NeedsThing
{
private readonly IThingINeedFactory _factory;
public NeedsThing(IThingINeedFactory factory)
{
_factory = factory;
}
public string PerformSomeFunction(ThingTypes valueThatDeterminesTypeOfThing)
{
var thingINeed = _factory.Create(valueThatDeterminesTypeOfThing);
try
{
//This is just for demonstration purposes. The method
//returns the name of the type created by the factory
//so you can tell that the factory worked.
return thingINeed.GetType().Name;
}
finally
{
_factory.Release(thingINeed);
}
}
}
public enum ThingTypes
{
A, B, C, D
}
public class ContainerConfiguration
{
public void Configure(IUnityContainer container)
{
container.RegisterType<IThingINeedFactory,ThingINeedFactory>(new InjectionConstructor(container));
container.RegisterType<IThingINeed, ThingA>("ThingA");
container.RegisterType<IThingINeed, ThingB>("ThingB");
container.RegisterType<IThingINeed, ThingC>("ThingC");
container.RegisterType<IThingINeed, ThingC>();
}
}
Here's some unit tests. They show that the factory returns the correct type of IThingINeed after inspecting what was passed to its Create() function.
In this case (which may or may not be applicable) I also specified one type as a default. If nothing is registered with the container that exactly matches the requirement then it could return that default. That default could also be a null instance with no behavior. But all of that selection is in the factory and container configuration.
[TestClass]
public class UnitTest1
{
private IUnityContainer _container;
[TestInitialize]
public void InitializeTest()
{
_container = new UnityContainer();
var configurer = new ContainerConfiguration();
configurer.Configure(_container);
}
[TestCleanup]
public void CleanupTest()
{
_container.Dispose();
}
[TestMethod]
public void ThingINeedFactory_CreatesExpectedType()
{
var factory = _container.Resolve<IThingINeedFactory>();
var needsThing = new NeedsThing(factory);
var output = needsThing.PerformSomeFunction(ThingTypes.B);
Assert.AreEqual(output, typeof(ThingB).Name);
}
[TestMethod]
public void ThingINeedFactory_CreatesDefaultyTpe()
{
var factory = _container.Resolve<IThingINeedFactory>();
var needsThing = new NeedsThing(factory);
var output = needsThing.PerformSomeFunction(ThingTypes.D);
Assert.AreEqual(output, typeof(ThingC).Name);
}
}
This same factory can be implemented using Windsor, and the factory in the Windsor example could be done in Unity.

Castle Windsor multiple implementations of interface

I have the following installer but for some odd reason it is not resolving correctly. I have an interface where there are 2 implementations of it but want to inject the correct instance based on naming conventions.
I am expecting in this instance that the correct instance of ICommand will be injected based on how they are named. However, for some odd reason both controllers are picking the very first instance, i.e. FooCommand due to it being defined first in the installer.
Not sure what I have done wrong? Perhaps, is there an alternative way of doing this?
public interface ICommand { }
public class FooCommand : ICommand { }
public class BarCommand : ICommand { }
public class SomeController : ApiController
{
public SomeController(ICommand fooCommand) { }
}
public class HelloController : ApiController
{
public HelloController(ICommand barCommand) { }
}
container.Register(
Component.For<ICommand>()
.Named("fooCommand")
.ImplementedBy<FooCommand>()
.LifestyleSingleton(),
Component.For<ICommand>()
.Named("barCommand")
.ImplementedBy<BarCommand>()
.LifestyleSingleton());
Like #steven said, it's generally not a good idea and if not managed properly may lead to discoverability issues down the line, but assuming you know what you're doing you can build a IContributeComponentModelConstruction that will match constructor parameters of type ICommand on your controllers with Windsor components having the same name.
public class ControllerCommandMatcher : IContributeComponentModelConstruction
{
public void ProcessModel(IKernel kernel, ComponentModel model)
{
// or whatever other condition to bail out quickly
if (model.Implementation.Name.EndsWith("Controller") == false) return;
foreach (var constructor in model.Constructors)
{
foreach (var dependency in constructor.Dependencies)
{
if (dependency.TargetItemType != typeof (ICommand)) continue;
dependency.Parameter = new ParameterModel(dependency.DependencyKey,
ReferenceExpressionUtil.BuildReference(dependency.DependencyKey));
}
}
}
}
The tricky bit is this:
new ParameterModel(dependency.DependencyKey,
ReferenceExpressionUtil.BuildReference(dependency.DependencyKey))
It basically tells Windsor that the dependency (the constructor parameter), for example fooCommand should be satisfied with a component of the same name (fooCommand).
Then add your contributor to the container
container.Kernel.ComponentModelBuilder.AddContributor(new ControllerCommandMatcher());
Here's the documentation

Inject a component property into another component's constructor parameter with Autofac

With Autofac IoC container, say one has the following scenario:
public interface IHaveASpecialProperty
{
SpecialType SpecialProperty { get; }
}
public class HaveASpecialPropertyImpl : IHaveASpecialProperty
{
// implementation
}
public class SomeComponent
{
public SomeComponent(SpecialType special)
{
_special = special;
// rest of construction
}
private readonly SpecialType _special;
// implementation: do something with _special
}
// in composition root:
containerBuilder.RegisterType<HaveASpecialPropertyImpl>
.As<IHaveASpecialProperty>();
containerBuilder.RegisterType<>(SomeComponent);
Is there a way to register, within Autofac container, the HaveASpecialPropertyImpl type to act as a kind of provider/ factory of SpecialType instances?
What I currently have is this classic approach:
public class SomeComponent
{
public SomeComponent(IHaveASpecialProperty specialProvider)
{
_special = specialProvider.SpecialProperty;
// rest of construction
}
private readonly SpecialType _special;
// implementation: do something with _special
}
The rationale is basically related to the Law of Demeter: specialProvider is used only to grab a SpecialType instance, which instead is the actual dependency needed and used by SomeComponent, so it seems reasonable to just inject that SpecialType instance, without concerning SomeComponent on where that instance comes from.
PS: I've read about Delegate Factories, not sure if that's the (only?) way to go.
You can register a delegate :
builder.Register(c => c.Resolve<IHaveASpecialProperty>().SpecialProperty)
.As<ISpecialType>();
Using this registration, each time you will resolve a ISpecialType Autofac will resolve a IHaveASpecialProperty and return the SpecialProperty property value as ISpecialType.

resolving constructor dependency at runtime (without attributes)

I am using Unity for dependency injection and I want to control at runtime, which particular type is resolved and passed into a constructor as a dependency.
I have an interface:
public interface IDatabase
{
void DoSomething();
}
That is implemented by two classes:
public class SQLDatabase : IDatabase
{
public void DoSomething()
{
//Do Something on a SQL server database...
}
}
public class OracleDatabase : IDatabase
{
public void DoSomething()
{
//Do Something on an Oracle database...
}
}
A third class has a dependency on IDatabase
public class DataService: IDataService
{
public DataService(IDatabase database)
{
database.DoSomething();
}
}
The module registers each class with Unity and the two IDatabase types are given specific names so that they can be differentiated:
container.RegisterType<IDatabase, SQLDatabase>("SQLDatabase");
container.RegisterType<IDatabase, OracleDatabase>("OracleDatabase");
container.RegisterType<IDataService, DataService>();
I need to create an instance of a Consumer, at which point I want to specify which of the two types that implement IDatabase are to be used/injected by Unity, but I don't know how to tell Unity which specific type to construct/resolve? I guess I want something like this (Pseudo code):
public class Consumer
{
IDataService dataService = null;
public Consumer(string runtimeChoice)
{
if (runtimeChoice == "SQLSERVER")
{
dataService = _container.Resolve<IDataService>("SQLDatabase");
}
else if (runtimeChoice == "Oracle")
{
dataService = _container.Resolve<IDataService>("OracleDatabase");
}
}
}
So, how do I tell Unity to resolve the IDatabase type, using the specific named type, and pass it into the constructor of dependent objects, but doing it at runtime?
There are two things I would change, I would try to ensure those magic strings were handled as close to their source as possible and I would try to ensure my code was container agnostic.
I would have the following interface:
public interface IDataServiceFactory
{
IDataService CreateSqlDataService();
IDataService CreateOracleDataService();
}
With an implementation like so:
public class DataServiceFactory : IDataServiceFactory
{
private readonly Func<IDataService> _sqlDataServiceFactory;
private readonly Func<IDataService> _oracleDataServiceFactory;
public DataServiceFactory(Func<IDataService> sqlDataServiceFactory, Func<IDataService> oracleDataServiceFactory)
{
_sqlDataServiceFactory = sqlDataServiceFactory;
_oracleDataServiceFactory = oracleDataServiceFactory;
}
public IDataService CreateSqlDataService()
{
return _sqlDataServiceFactory();
}
public IDataService CreateOracleDataService()
{
return _oracleDataServiceFactory();
}
}
I would then register this with your IUnityContainer like so:
_container.RegisterType<IDataService, DataService>("SQLDataService",
new InjectionConstructor(new ResolvedParameter<IDatabase>("SQLDatabase")));
_container.RegisterType<IDataService, DataService>("OracleDataService",
new InjectionConstructor(new ResolvedParameter<IDatabase>("OracleDatabase")));
_container.RegisterType<IDataServiceFactory, DataServiceFactory>(new InjectionConstructor(
new ResolvedParameter<Func<IDataService>>("SQLDataService"),
new ResolvedParameter<Func<IDataService>>("OracleDataService"));
Now whatever was previously creating your Consumer instances should now have a dependency on IDataServiceFactory and should handle the runtime value to call the correct method CreateSqlDataService() or CreateOracleDataService().
All of your runtime code is now container agnostic and the magic strings are handled right next to their source.
I was able to resolve the correct type using a DependencyOverride, which itself obtained the required type from the unity container. So the consumer becomes:
public class Consumer
{
IDataService dataService = null;
public Consumer(string runtimeChoice)
{
DependencyOverride<IDatabase> dependency = null;
if (runtimeChoice == "SQLSERVER")
{
dependency = new DependencyOverride<IDatabase>
(Container.Resolve<IDatabase>("SQLDatabase"));
}
else if (runtimeChoice == "Oracle")
{
dependency = new DependencyOverride<IDatabase>
(Container.Resolve<IDatabase>("OracleDatabase"));
}
dataService = _container.Resolve<IDataService>(dependency);
}
}
I have a similar requirement where I need to resolve a 'widgetbuilder' type at runtime. In my Unity Configuration I register my two types of widget builders:-
container.RegisterType<IWidgetBuilder, SinglePointWidgetBuilder>("SinglePointWidgetBuilder");
container.RegisterType<IWidgetBuilder, CurrentVsTargetWidgetBuilder>("CurrentVsTargetWidgetBuilder");
I then resolve them at runtime by:-
var container = UnityConfig.GetConfiguredContainer();
var widgetBuilder = container.Resolve<IWidgetBuilder>("SinglePointWidgetBuilder");

Inject same DataContext instance across several types with Unity

Suppose I have IRepository interface and its implementation SqlRepository that takes as an argument LINQ to SQL DataContext. Suppose as well that I have IService interface and its implementation Services that takes three IRepository, IRepository and IRepository. Demo code is below:
public interface IRepository<T> { }
public class SqlRepository<T> : IRepository<T>
{
public SqlRepository(DataContext dc) { ... }
}
public interface IService<T> { }
public class Service<T,T1,T2,T3> : IService<T>
{
public Service(IRepository<T1> r1, IRepository<T2>, IRepository<T3>) { ... }
}
Is it any way while creating Service class to inject all three repositories with the same DataContext?
All you need to do is make sure when you register the Datacontext with your Unity container use the PerResolveLifetimeManager either in config:
<type type="<namespace>.DataContext, <assembly>">
<lifetime type="Microsoft.Practices.Unity.PerResolveLifetimeManager, Microsoft.Practices.Unity" />
</type>
or in code:
container.RegisterType<DataContext>(new PerResolveLifetimeManager());
then whenever the container resolves the Service any dependencies which also require a DataContext will be provided with exactly the same one. But the next request to resolve Service will create a new DataContext.
I think I know what you want to do. I'm in the same boat and am trying to come up with a solution.
My Service layer performs operations on in coming requests, and what it does depends on the contents. It passes it to a series of chain of responsibility classes. I want the same context passed to all classes within the lifetime of the service method called
You can Specify PerResolveLifetimeManager. So far, it seems to be working with my test cases:
Service Class:
public interface IServiceClass
{
void DoService();
}
class ServiceClass : IServiceClass
{
private IHandler Handler { get; set; }
public ServiceClass(IHandler handler)
{
Handler = handler;
}
public void DoService()
{
Handler.HandleRequest();
}
}
IHandler is implemented by two classes, and performs Chain of Responsibility pattern:
public interface IHandler
{
void HandleRequest();
}
class Handler : IHandler
{
private IDataContext DataContext { get; set; }
public Handler(IDataContext dataContext)
{
DataContext = dataContext;
}
public void HandleRequest()
{
DataContext.Save("From Handler 1");
}
}
class Handler2 : IHandler
{
private IDataContext DataContext { get; set; }
private IHandler NextHandler { get; set; }
public Handler2(IDataContext dataContext, IHandler handler)
{
DataContext = dataContext;
NextHandler = handler;
}
public void HandleRequest()
{
if (NextHandler != null)
NextHandler.HandleRequest();
DataContext.Save("From Handler 2");
}
}
As you can see, both handlers accept an instance of IDataContext, which I want to be the same in both of them. Handler2 also accepts an instance of IHandler to pass control to (it does both here to demonstrate, but actually, only one would handle the request...)
IDataContext. In the constructor I initialize a Guid, and during its operation, output it so I can see if both times its called is using the same instance:
public interface IDataContext
{
void Save(string fromHandler);
}
class DataContext : IDataContext
{
private readonly Guid _guid;
public DataContext()
{
_guid = Guid.NewGuid();
}
public void Save(string fromHandler)
{
Console.Out.WriteLine("GUI: [{0}] {1}", _guid, fromHandler);
}
}
Finally, registration and calling of service:
private IUnityContainer container;
private void InitializeUnity()
{
container = new UnityContainer();
container.RegisterType<IHandler, Handler2>("Handler2",
new InjectionConstructor(new ResolvedParameter<IDataContext>(), new ResolvedParameter<IHandler>("Handler1")));
container.RegisterType<IHandler, Handler>("Handler1");
container.RegisterType<IDataContext, DataContext>(new PerResolveLifetimeManager());
container.RegisterType<IServiceClass, ServiceClass>("MyClass", new InjectionConstructor(new ResolvedParameter<IHandler>("Handler2")));
}
private void CallService()
{
var service = container.Resolve<ServiceClass>("MyClass");
service.DoService();
// Resolving and calling again to simulate multiple resolves:
service = container.Resolve<ServiceClass>("MyClass");
service.DoService();
}
This is the output I get:
GUI: [f2250055-8a5f-4f80-a1b6-bcc5574138cf] From Handler 1
GUI: [f2250055-8a5f-4f80-a1b6-bcc5574138cf] From Handler 2
GUI: [22a5c0a3-3c5c-4683-807d-bf2b43f3cd0a] From Handler 1
GUI: [22a5c0a3-3c5c-4683-807d-bf2b43f3cd0a] From Handler 2
Hope this wall of text answered your question... If not sorry, it did inspire a solution I needed to implement...
If I understand your question correctly (and if you are using unity...I suppose you do because you have taggged it with unity) you could do something like this:
In your repository implementions,
[InjectionConstructor]
public SqlRepository(
[Dependency] DataContext ctx)
but then you have to mark the service contructor in the same manner and use the container to resolve your services as well as the repository. The DataContext also has to be in the container to make it work.
An alternative approach is to do something like this with your repository:
[InjectionMethod]
public void Initialize(
[Dependency] DataContext ctx
this will tell unity to call this method if you will, in your service constructor, use unity with the BuildUp method...something like this:
unitycontainer.BuildUp<IRepository>(repository);
I guess that´s not quite what your looking for but please tell me if I´m on the right track and I´ll see if I can help you further...
Cheers / J
Have you tried using the RegisterInstance() method for the unity container? Something like this might work:
public static UnityContainer CreateContainer()
{
UnityContainer container = new UnityContainer();
try
{
var section = ConfigurationManager.GetSection("unity") as UnityConfigurationSection;
if (section != null)
{
section.Containers[0].Configure(container);
}
}
catch (Exception ex)
{
TraceLogger.LogMessage("Configurarion Error for Unity Container", ex.Message, TraceEventType.Critical);
Environment.Exit(1);
}
container.RegisterInstance(new DataContext());
return container;
}
Now, every time this container tries to build an object which needs a DataContext, the same instance will be passed. You could even configure the DataContext before registering its instance.
UPDATE:
One option (now, I don't know if its really a good practice, but this worked for me) is to create a different container for each object you're gonna create. Something like:
UnityContainer container1 = ContainerFactory.CreateContainer();
UnityContainer container2 = ContainerFactory.CreateContainer();
UnityContainer container3 = ContainerFactory.CreateContainer();
MyObject1 object1 = container1.Resolve<MyObject1>();
MyObject2 object2 = container2.Resolve<MyObject2>();
MyObject3 object3 = container3.Resolve<MyObject3>();
or a more summarized way:
MyObject1 object1 = ContainerFactory.CreateContainer().Resolve<MyObject1>();
MyObject1 object2 = ContainerFactory.CreateContainer().Resolve<MyObject2>();
MyObject1 object3 = ContainerFactory.CreateContainer().Resolve<MyObject3>();
Well, there's a lot of ways to do it, creating a list, using the factory pattern. Hope it helps

Categories