resolving constructor dependency at runtime (without attributes) - c#

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

Related

how to pass generic interface in constructor of a class with type of that class with autofac

I have the following classes and interfaces in c#. I cant figure out how to register them with AutoFac.
public interface ICustomer{void Validate();}
public interface IValidation<T>{void Validate(T obj);}
public class CustomerBase : ICustomer
{
private IValidation<ICustomer> validation = null;
public CustomerBase(IValidation<ICustomer> obj)
{
validation = obj;
}
public virtual void Validate()=>validation.Validate(this);
}
public class Lead : CustomerBase
{
public Lead(IValidation<ICustomer> obj) : base(obj){}
}
public class LeadValidation : IValidation<ICustomer>
{
public void Validate(ICustomer obj){//Now validation Here......}
}
You need to register your components for the Dependency Injection. That's done by creating a ContainerBuilder and registering your components.
// create the ContainerBuilder
var builder = new ContainerBuilder();
// register your components
builder.RegisterType<MyConcreteType1>().As<IMyInterface1>();
builder.RegisterInstance(new MyConcreteType2()).As<IMyInterface2>();
...
// build your container
var myContainer = builder.Build();
And then to get your required component all you have to do is
// create a scope so AutoFac will take care of
// disposing of objects you no longer need
using (var scope = myContainer.BeginLifetimeScope())
{
// resolve the components you need. AutoFac will take care of
// resolving their dependencies and instantiating them for you
var requiredComponent = scope.Resolve<IMyInterface1>();
// now you can use your components!
}
Here's a very useful video that will help you understand how to use AutoFac and its purpose: https://www.youtube.com/watch?v=mCUNrRtVVWY

Simple Injector in Console Application with multiple projects and an abstract factory

TL;DR. I have a circular dependency and no idea how to break it.
Main.csproj: has Program.cs which manually instantiates DiService
var diService = new DiService(new Container());
diService.Register();
The register method searches CurrentDomain for assemblies and registers collections where multiple implementations exist for a given interface or else registers concretions on a 1-1 basis.
It then uses the Container to instantiate an abstract factory.
var diFactory = diService.Registry.GetInstance<IDiFactory>();
Here's the factory
public class DiFactory : IDiFactory
{
private readonly Container registry;
public DiFactory(Container registry)
{
this.registry = registry;
}
public T Get<T>()
{
var reqT = typeof(T);
return (T) registry.GetInstance(reqT);
}
}
The project dependencies in the solution look like this:
Main -> A -> B,E
B -> C,D,E
C -> D,E
D -> E
DiService and DiFactory live in project B with the other services. Not that it matters. I think I'd have the same problem if they were in Main.
All objects in projects B to E have a constructor injected DiFactory so they can decide what objects they need at run time. But for C to make use of it, it must depend on B, which is a circular dependency.
If I move the DI stuff to a new project F, then all projects can depend on that but how does the factory reference the types in the other projects without creating another circular dependency?
I followed the documentation for IRequestHandler, I just didn't do the dictionary. Most likely I have a design flaw but I can't see what it is.
Here's an example of the interactions between objects for LinqPad - doesn't compile but it looks right.
void Main()
{
var diService = new Mine.Services.MyDiService();
var diFactory = diService.Container.GetInstance<Mine.Services.IMyFactory>();
var rand = new Random();
var next = rand.Next(1, 100);
var task = next % 2 == 0
? diFactory.Get<Mine.Tasks.EvenTask>()
: (Mine.Tasks.IMyTask)diFactory.Get<Mine.Tasks.OddTask>();
task.Perform();
}
namespace Mine.Common
{
public class MyCommonObject { }
}
namespace Mine.Services
{
public class FakeContainer
{
public T GetInstance<T>() { return default(T); }
}
public interface IMyOtherService { void DoSomethingElse(); }
public class MyOtherService : IMyOtherService
{
public void DoSomethingElse()
{
throw new NotImplementedException();
}
}
public class MyService
{
private readonly IMyFactory myFactory;
public MyService(IMyFactory myFactory)
{
this.myFactory = myFactory;
}
public void MyServiceMethod()
{
var thing = myFactory.Get<Mine.Common.MyCommonObject>();
}
}
public interface IMyFactory { T Get<T>(); }
public class MyDiService
{
public FakeContainer Container;
}
public class MyFactory : IMyFactory
{
private FakeContainer Container;
public MyFactory(FakeContainer container)
{
// obviously this is really a SImple Injector Container
Container = container;
}
public T Get<T>()
{
return default(T);
}
}
}
namespace Mine.Kernel {
public interface IMyMultiConcrete { void Do(); }
public class MyConcreteBase : IMyMultiConcrete
{
protected readonly Mine.Services.IMyFactory MyFactory;
public MyConcreteBase(Mine.Services.IMyFactory myFactory)
{
MyFactory = myFactory;
}
public void Do()
{
MyFactory.Get<Mine.Common.MyCommonObject>();
}
}
public class MyConcrete1 : MyConcreteBase
{
public MyConcrete1(Mine.Services.IMyFactory myFactory) : base(myFactory) {}
public void Do()
{
MyFactory.Get<Mine.Common.MyCommonObject>();
}
}
}
namespace Mine.Tasks
{
public interface IMyTask { void Perform(); }
public class TaskBase : IMyTask
{
protected readonly Mine.Services.IMyOtherService MyOtherService;
public TaskBase(Mine.Services.IMyFactory myFactory, Mine.Services.IMyOtherService myOtherService)
{
MyOtherService = myOtherService;
}
public void Perform()
{
MyOtherService.DoSomethingElse();
}
}
public class OddTask : TaskBase
{
public OddTask(Mine.Services.IMyFactory myFactory, Mine.Services.IMyOtherService myOtherService)
: base(myFactory, myOtherService) { }
}
public class EvenTask : TaskBase
{
public EvenTask(Mine.Services.IMyFactory myFactory, Mine.Services.IMyOtherService myOtherService)
: base(myFactory, myOtherService) { }
}
}
This IDiFactory abstraction you are describing is not an implementation of the Abstract Factory design pattern—it is an implementation of the Service Locator pattern. Service Locator, however, is an anti-pattern and you should stop using it because its numerous downsides.
Instead, classes should not be able to request an unbound set of dependencies from a Service Locator, but neither should they typically be able to request a fixed set of dependencies using an Abstract Factory. Instead, classes should statically declare their required dependencies through the constructor.
This change might already fix the circular dependency as you will remove the IDiFactory (that is causing the cycle) in the first place.
DiService and DiFactory live in project B with the other services. Not that it matters.
It does matter where you wire up your dependencies. Dependencies should be wired up in your Composition Root and this Composition Root should live
As close as possible to the application’s entry point.
This most likely means that you should move this to your Console application. When you move that code, only the start-up assembly will take a dependency on the used DI Container. At that point, it becomes irrelevant to hide the DI Container behind an Abstraction (as your DiService seems to imply). Hiding is not needed anymore, because no other parts of the application except the Composition Root will have any knowledge about how dependency graphs are built. Hiding the DI Container behind an abstraction, at that point, doesn't increase maintainability any longer.
There might be an easier way, but what I typically end up doing is to have a separate assembly containing interfaces for everything I need to inject.
The main assembly (or B could do it in your case) performs the binding of interfaces to concrete implementations and everyone can reference the interfaces assembly without creating any circular dependencies.
The interface for the factory should also be in that assembly.

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.

Can MEF resolve a Func delegate returning an interface?

Code at bottom is from a working WPF sample application that used Autofac for dependency injection.
I want to convert to latest version of MEF instead. I also have NuGet packages CommonServiceLocator (V. 1.3) and Prism.Core, Prism.Mef and Prism.Wpf (all 6.1) installed.
When I do
var provider = ServiceLocator.Current.GetInstance<FriendDataProvider>();
I get an ActivationException from the "Func..." declaration in the constructor of FriendDataProvider.
Can MEF do this at all? If yes, what attribute declarations are required?
[Export]
public class FriendDataProvider
{
private readonly Func<IDataService> _dataServiceCreator;
[ImportingConstructor]
public FriendDataProvider(Func<IDataService> dataServiceCreator) // <= DI ERROR
{
_dataServiceCreator = dataServiceCreator;
}
public void DoSomething()
{
using (var service = _dataServiceCreator()) // Factory
{ }
}
}
[Export(typeof(IDataService))]
public class DataService : IDataService
{
public ClassA GetSomething()
{
return new ClassA();
}
public void Dispose()
{ }
}
public interface IDataService : IDisposable
{
ClassA GetSomething();
}
public class ClassA
{ }
Most likely you are looking for MEF ExportFactory class:
https://msdn.microsoft.com/en-us/library/ff382807(v=vs.110).aspx
It'a a mixture of Owned<> and Func<> ideas from AutoFac. Mind that ExportFactory.CreateExport returns ExportLifetimeContext which is Disposable. Disposing the export lifetime context will also dispose the injected part + all its dependencies. ExportFactory behavior is slightly different depending on Instancing mode of the owner part. If the owner class is a singleton ExportFactory will always create you new instance (behaves like Func< Owned< T>> in Autofac), but if you use it in combination with CompositionScopes you'll get behavior similar to Func< T> in AutoFac. See example: http://blogs.microsoft.co.il/bnaya/2013/01/16/mef-20-mini-series-part-6-composition-scoping-and-lifetime-management/
Here is your example re-written using ExportFactories:
[Export]
public class FriendDataProvider
{
private readonly ExportFactory<IDataService> _dataServiceCreator;
[ImportingConstructor]
public FriendDataProvider(ExportFactory<IDataService> dataServiceCreator) // <= DI ERROR
{
_dataServiceCreator = dataServiceCreator;
}
public void DoSomething()
{
using (var service = _dataServiceCreator.CreateExport()) // Factory
{
}
}
}
[Export(typeof(IDataService))]
public class DataService : IDataService
{
public ClassA GetSomething()
{
return new ClassA();
}
public void Dispose()
{ }
}
public interface IDataService : IDisposable
{
ClassA GetSomething();
}
public class ClassA
{ }

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