Here's what I want to be able to do in my application:
public void BusinessLogic (IFactory workerFactory)
{
string specificObjectType = ... // not known in advance
IWorkerObject workerObject = workerFactory.CreateByType(specificObjectType);
workerObject.DoActualWork();
}
In other words, I want an actual Factory that generates various kinds of IWorkerObject implementations on demand, and I want that Factory to be injectable. And ideally that Factory itself would be able to get those implementation object from the service container too:
public class WorkerFactory
{
public WorkerFactory (IServiceContainer ...)
{ ... }
public IWorker CreateByType (string type)
{
return ...; // a thing that can be provided by the service container
}
}
The reason is that I want to be able to create (for example) a SteelWorker or a CopperWorker or an AluminumWorker depending on what type of metal is represented by that specificObjectType value. This seems like a normal Factory pattern to me, but I don't know how to make a class injectable and give it parameters that aren't resolved until creation time.
If this can be done with Unity, great. If I need to work around it or use another DI framework, that is okay too.
You could inject an IServiceScopeFactory into the IFactory
using (var scope = _serviceScopeFactory.CreateScope())
{
if(criteriaA)
{
return scope.ServiceProvider.GetRequiredService<WorkerA>();
}
}
I am trying to get IoC working with Unity in C# with the idea of a passing a wrapper/composite class into the children.
The top level class that composes multiple classes provides some common functionality that the composed classes require access to.
To illustrate:
// The top composite class
public class Context : IContext {
public ISomething SomethingProcessor { get; }
public IAnother AnotherProcessor { get; }
public Context(ISomething something, IAnother another) {
this.SomethingProcessor = something;
this.AnotherProcessor = processor;
}
// A function that individual classes need access to, which itself calls one of the children.
public string GetCommonData() {
return this.AnotherProcessor.GetMyData();
}
}
public class Something : ISomething {
private _wrapper;
public Something(IContext context) {
this._wrapper = context;
}
// This class has no knowledge of IAnother, and requests data from the master/top class, which knows where to look for whatever.
public void Do() {
Console.WriteLine(_wrapper.GetCommonData());
}
}
public class Another : IAnother {
public string GetMyData() {
return "Foo";
}
}
If you didn't use IoC, it's easy, as the constructor for the Context class becomes:
public Context() {
this.SomethingProcessor = new Processor(this);
this.AnotherProcessor = new Another();
}
But when you're using IoC, the idea of "this" doesn't exist yet because it is yet to be constructed by the injector. Instead what you have a is a circular dependency.
container.RegisterType<ISomething, Something>();
container.RegisterType<IAnother, Another>();
container.RegisterType<IContext, Context>();
var cxt = container.Resolve<IContext>(); // StackOverflowException
The above example has been greatly simplified to illustrate the concept. I'm struggling to find the "best practice" way of dealing with this kind of structure to enable IOC.
Factory pattern is a way construct an object based on other dependencies or logical choices.
Factory Method: "Define an interface for creating an object, but let
the classes which implement the interface decide which class to
instantiate. The Factory method lets a class defer instantiation to
subclasses" (c) GoF.
Lots of construction.. hence the name Factory Pattern
A crude code sample that could be used with DI
public class ContextFactory : IContextFactory {
_anotherProcessor = anotherProcessor;
public ContextFactory(IAnotherProcessor anotherProcessor) {
//you can leverage DI here to get dependancies
}
public IContext Create(){
Context factoryCreatedContext = new Context();
factoryCreatedContext.SomethingProcessor = new SomethingProcessor(factoryCreatedContext )
factoryCreatedContext.AnotherProcessor = _anotherProcessor;
//You can even decide here to use other implementation based on some dependencies. Useful for things like feature flags.. etc.
return context;
}
}
You can get away with this, maybe? - but there is still the cyclic reference issue here and I would never commit this kind of code.
The problem here you need to concentrate on Inversion Of Control of that GetCommonData
Your SomethingProcessor should not rely on methods in another class. This is where In Inheritance could be used but Inheritance can become very complicated very quickly.
The best way forward is to Identify the ONE thing that is needed by both or many other places and break that out into a new Dependency. That is how you Invert Control.
TIP:
Don't overdo Interfaces- Use Interfaces where you think you will be working with Polymorphism, such as a collection of different objects that must promise you they have implemented a specific method/property. Otherwise you are over using Interfaces and increasing complexity. DI doesn't have to use Interfaces it can be a concrete implementation. Interfaces on Repositories are a good use since you can switch Databases out easily but Interfaces a factory like this is not really needed.
I don't know the name of this pattern, or even if it is a bad or good practice, but you can solve your problem of "double-binding" by creating a method to bind the "IContext", instead of doing it in the constructor.
For instance,
1) ISomething has a void BindContext(IContext context) method
2) You implement it as such :
class Something : ISomething
{
IContext _wrapper;
// ... nothing in constructor
public void BindContext(IContext context)
{
_wrapper = context;
}
}
3) Remove the IContext dependency injection in Something constructor.
And you call it from the context constructor :
public Context(ISomething something, IAnother another) {
this.SomethingProcessor = something;
this.SomethingProcessor.BindContext(this);
// same for IAnother
}
And you do the same for IAnother. You could even extract some common interface "IBindContext" to make things a beat more "DRY" (Don't Repeat yourself) and make IAnother and ISomething inherit from it.
Not tested, and again : not sure it's the best way to do such dependency design. I'll be glad if there is another answer which gives a state-of-the-art insight about this.
Background / Goal
We have several "client sites" on our web app that users can switch between
We do a lot of wiring up of objects based on factories that take in the client site ID and create an instance
I would like to inject these dependencies into the classes instead
I also want to make sure I can pass in my own implementations to the constructor for the purposes of unit testing.
We have initially elected to use StructureMap 3.x to do so, but are open to alternatives if they can help us solve this scenario gracefully.
Question
In instances where I require a different dependency based on a client site ID that I'll only get at run-time, what is the appropriate way to set up an IoC container and the appropriate way to request the object from it in order to make it as painless as possible?
Am I thinking about this wrong and unintentionally creating some sort of anti-pattern?
Example Code
Normally we're doing something like the following coming in:
public class MyService
{ DependentObject _dependentObject;
public MyService(int clientSiteID)
{
// ...
_dependentObject = new dependentObjectFactory(clientSiteID).GetDependentObject();
}
public void DoAThing()
{
//...
_dependentObject.DoSomething();
}
}
What I'd like to do:
public class MyService
{ DependentObject _dependentObject;
public MyService(int clientSiteID)
{
// ...
_dependentObject = MyTypeResolver.GetWIthClientContext<IDependentObject>(clientSiteID);
}
public MyService(int clientSiteID, IDependentObject dependentObject)
{
// ...
_dependentObject = dependentObject;
}
public void DoAThing()
{
//...
_dependentObject.DoSomething();
}
}
I would set up the IoC container in such a way that I can use my MyTypeResolver to pass in the clientSiteID, and have the container call my DependentObjectFactory and return the correct object result.
I'm new to IoC containers, and while I'm trying to plow through the literature, I have the feeling it may be easier than I'm making it so I'm asking here.
Probably the simplest way to do this is to use an Abstract Factory. Most IOC frameworks can auto-create them for you, but here's how you can do it manually (I always prefer to do it manually first so I know it works, and then you can check out how the framework can help you automagic it)
Now one thing to mention - I would recommend a slight readjustment of how the final solution works, but I'll go into that once I have shown how it can currently work. Example below assumes Ninject and please excuse any typos, etc.
First create an interface for your dependency
public interface IDependentObject
{
void DoSomething();
}
Then declare empty marker interfaces for each specific implementation of IDependentObject
public interface INormalDependentObject:IDependentObject{};
public interface ISpecialDependentObject:IDependentObject{}
and implement them:
public class NormalDependentObject:INormalDependentObject
{
readonly int _clientID;
public DependentObject(int clientID)
{
_clientID=clientID;
}
public void DoSomething(){//do something}
}
public class DependentObject:ISpecialDependentObject
{
readonly int _clientID;
public DependentObject(int clientID)
{
_clientID=clientID;
}
public void DoSomething(){//do something really special}
}
and of course as you mentioned you may have many more implementations of IDependentObject.
There may be a more elegant way of allowing your IOC framework to resolve at runtime without having to declare the marker interfaces; but for now I find it useful to use them as it makes the binding declarations easy to read :)
Next, declare an interface and implementation of an IDependentObjectFactory:
public interface IDependentObjectFactory
{
IDependentObject GetDependenObject(int clientID);
}
public class DependentObjectFactory: IDependentObjectFactory
{
readonly _kernel kernel;
public DependentObjectFactory(IKernel kernel)
{
_kernel=kernel;
}
public IDependentObject GetDependenObject(int clientID)
{
//use whatever logic here to decide what specific IDependentObject you need to use.
if (clientID==100)
{
return _kernel.Get<ISpecialDependantObject>(
new ConstructorArgument("clientID", clientID));
}
else
{
return _kernel.Get<INormalDependentObject>(
new ConstructorArgument("clientID", clientID));
}
}
}
Wire these up in your Composition Root:
_kernel.Bind<INormalDependentObject>().To<NormalDependentObject>();
_kernel.Bind<ISpecialDependentObject>().To<SpecialDependentObject>();
_kernel.Bind<IDependentObjectFactory>().To<DependentObjectFactory>();
and finally inject your factory into the service class:
public class MyService
{
IDependentObject _dependentObject;
readonly IDependentObjectFactory _factory;
//in general, when using DI, you should only have a single constructor on your injectable classes. Otherwise, you are at the mercy of the framework as to which signature it will pick if there is ever any ambiguity; most all of the common frameworks will make different decisions!
public MyService(IDependentObjectFactory factory)
{
_factory=factory;
}
public void DoAThing(int clientID)
{
var dependent _factory.GetDependentObject(clientID);
dependent.DoSomething();
}
}
Suggested changes
One immediate change from your structure above is that I have left clientID out of the service constructor and moved it to a method argument of DoAThing; this is because it makes a bit more sense to me that the Service itself would be stateless; of course depending on your scenario, you may want to not do that.
I mentioned that I had a slight adjustment to suggest , and it's this; the solution above depends (no pun!) on implementations of IDependentObject having a constructor with this signature:
public SomeDependency(int clientID)
If they don't have that signature then the factory won't work; personally I don't like my DI to have to know anything about constructor params because it takes you out of purely dealing with interfaces and forcing you to implement specific ctor signatures on your concrete classes.
It also means that you can't reliably make your IDependentObjects be part of the whole DI process (i.e whereby they themselves have dependency graphs that you want the framework to resolve) because of the forced ctor signature.
For that reason I'd recommend that IDependentObject.DoSomething() itself be changed to DoSomething(int clientID) so that you can elide the new ConstructorArgument part of the factory code; this means that your IDependentObject s can now all have totally different ctor signatures, meaning they can have different dependencies if needs be. Of course this is just my opinion, and you will know what works best in your specific scenario.
Hope that helps.
I am trying to inject two classes into my constructor, the problem they are both of the same interface. My registering is:
container.RegisterType<ITrackerSection, ScopeSection>();
container.RegisterType<ITrackerSection, SampleSection>();
As you can see they are both of type ITrackerSection but have different implementations. My constructor looks as follows:
public TrackerEngine(ITrackerSection scopeSection, ITrackerSection sampleSection)
Both these parameters are injected as a sampleSection as it was last to be registered for the interface type. I have no problem with naming the registered types for example
container.RegisterType<ITrackerSection, ScopeSection>("scopeSection");
container.RegisterType<ITrackerSection, SampleSection>("sampleSection");
But this now means I have to specify the classes parameters and that seems messy and adding dependency when unity is more than capable of resolving them. Furthermore the registering of the TrackerEngine would also need to specify the parameters. I know I could use an in line attribute in the constructor of TrackerEngine but I would prefer Unity to infer the objects by the names.
Can Unity (I can not seem to get this working) correctly inject the correct implementation of the interface purely from the name given to the parameter in the constructor? So ITrackerSection scopeSection is the same name given in the registering of ScopeSection so use that type.
I agree with the comments regarding sharing the interface. The whole point of IOC is that your engine should not need to know which implementation to use. It should only be given the interface.
A way to solve this is to allow Unity to inject an array of interfaces:
public TrackerEngine(ITrackerSection[] trackerSections) { }
This way you can inject both. But then, if you really need to know which interface is which, you could implement a enum or something in your interface. Something like this:
public interface ITrackerSection {
SectionType Section { get; }
}
public enum SectionType{
0 = Scope,
1 = Sample
}
And in your implementation:
public class ScopeTrackerSection : ITrackerSection {
// Do your stuff...
public SectionType Section {
get { return SectionType.Scope; }
}
}
public class SampleTrackerSection : ITrackerSection {
// Do your stuff...
public SectionType Section {
get { return SectionType.Sample; }
}
}
And in your Engine, you can fetch the interface needed to the desired action.
public TrackerEngine(ITrackerSection[] trackerSections) {
var scopeTrackerSection = trackerSections.FirstOfDefault(x => x.Section == SectionType.Sample);
// Do something with scopeTrackerSection
}
I'm trying to get my head around DI/IoC, NHibernate and getting them to work nicely together for an application that i'm developing. I'm quite new to both NHibernate and DI/IoC so not quite sure whether what i'm doing is the sensible way to be going about it. This is the scenario:
The application provides users with the ability to calculate a particular value (known as the margin) for a particular financial transaction. The calculation of the marging value for each transaction is carried out by concrete implementations of an abstract MarginCalculator class and the concrete implementation to be used depends on the type of the product for the particular transaction (given by a certain field of the product object). The concrete calculator class is accessed via a property on the product class. i.e.
public class Transaction
{
private double _margin;
private Product _product;
private Client _client;
public double Margin { get; }
public Product Product { get; }
public Client Client { get; }
public Transaction(Product p, Client c)
{
_product = p;
_client = c;
}
public void CalculateMargin()
{
_margin = _product.MarginCalculator.CalculateMargin();
}
}
public class Product
{
private string _id;
private string _productType;
... Other fields
public string Id { get; }
public string ProductType { get; }
public MarginCalculator MarginCalculator
{
get { return MarginCalculatorAssembler.Instance.CreateMarginCalculatorFor(this.ProductType); }
}
}
public class MarginCalculatorAssembler
{
public static readonly MarginCalculatorAssembler Instance = new MarginCalculatorAssembler();
private MarginCalculatorAssembler ()
{
}
public MarginCalculator CreateMarginCalculatorFor(string productType)
{
switch (productType)
{
case "A":
return new ConcreteMarginCalculatorA();
case "B":
return new ConcreteMarginCalculatorB();
default:
throw new ArgumentException();
}
}
}
public abstract class MarginCalculator
{
public abstract double CalculateMargin();
}
public class ConcreteMarginCalculatorA : MarginCalculator
{
public override double CalculateMargin
{
// Perform actual calculation
}
}
public class ConcreteMarginCalculatorB : MarginCalculator
{
public override double CalculateMargin
{
// Perform actual calculation
}
}
Users select a particular client and Product from dropdowns and the corresponding clientId and productId are passed to repositories that then use NHibernate to populate product and client objects before they're injected into the transaction object. In my current setup the Transaction receives its Product and Client dependencies via constructor dependency injection (no IoC container used as yet) i.e.
public class ProductRepository : IRepository<Product>
{
public Product GetById(string id)
{
using (ISession session = NHibernateHelper.OpenSession())
return session.Get<Product>(id);
}
}
/* Similar repository for Clients */
IRepository<Client> clientRepository = new ClientRepository();
IRepository<Product> productRepository = new ProductRepository();
Client c = clientRepository.GetById(clientId);
Product p = productRepository.GetById(productId);
Transaction t = new Transaction(p, c);
The following are what i'm hoping to get ideas on:
A. Is it considered OK to be accessing the MarginCalculator (which is essentially a service) through the Product domain object or should, as suggested here, (http://stackoverflow.com/questions/340461/dependency-injection-with-nhibernate-objects) the code be restructured so as to remove service dependencies from the domain objects and instead create a new TransactionProcessor class that takes the abstract MarginCalculator as a dependency (along the lines of what's described here (http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/03/31/ptom-the-dependency-inversion-principle.aspx) i.e.
public class TransactionProcessor
{
private readonly MarginCalculator _marginCalculator;
public TransactionProcessor(MarginCalculator marginCalculator)
{
_marginCalculator = marginCalculator;
}
public double CalculateMargin(Transaction t)
{
return _marginCalculator.CalculateMargin(Transaction t);
}
}
public abstract class MarginCalculator
{
public abstract double CalculateMargin(Transaction t);
}
B. Is it possible to use an IoC Container to get a Transaction object with NHibernate populated/generated Product and Client dependencies injected? i.e. Given a productId and clientId, both provided by the user, is it possible to have something like:
// pseudocode
Transaction t = IoC.Resolve<Transaction>(productId, clientId);
such that the container resolves the Product and Client dependencies of the Transaction object, NHibernate is utilised to populate the Product and Client based on the productId and clientId and then the populated Product and Client are injected into the Transaction?
C. In a typical DI scenario, if class A has a dependency on interface B then the following might be done:
IInterfaceB b = new ClassB();
A a = new A(b);
interface IInterfaceB
{
}
class B : IInterfaceB
{
}
public class A
{
private IIntefaceB _b;
public A(IInterfaceB b)
{
_b = b;
}
}
However, this, which is virtually how all examples of DI are shown, assumes that the implementor of IInterfaceB (in this case Class B) is known at design time. Is there a way to use DI in such a way that the implementor is determined at runtime?
Many thanks
Matthew
A) If you're going to access the MarginCalculator through the Product domain object, you might as well cut out the middle man and let the DI/IOC container inject the MarginCalculator for you. You can even get rid of the MarginCalculatorAssembler because most DI/IOC containers do most of the boilerplate code of object construction for you.
B and C) It's very possible. In fact, here's how your code would look like if you used LinFu:
// No need to change the Transaction class
public class Transaction
{
private double _margin;
private Product _product;
private Client _client;
public double Margin { get; }
public Product Product { get; }
public Client Client { get; }
public Transaction(Product p, Client c)
{
_product = p;
_client = c;
}
public void CalculateMargin()
{
_margin = _product.MarginCalculator.CalculateMargin();
}
}
It would be nice if you could get a DI/IOC to inject the product and client instances into the constructor--but before we do that, you need to register the dependencies with the container. Here's how you do it with LinFu.IOC:
// Next, you'd have to tell LinFu to automatically register your product class:
[Factory(typeof(Product))]
public class ProductFactory : IFactory
{
object CreateInstance(IServiceRequest request)
{
// Grab a copy of the IRepository from the container
var repository = container.GetService>();
// Get the id (this assumes that your id is an Int32)
var id = (int)request.Arguments[0];
// Return the product itself
return repository.GetById(id);
}
}
// Do the same thing with the Client class
// (Note: I did a simple cut and paste to keep things simple--please forgive the duplication)
[Factory(typeof(Client))]
public class ClientFactory : IFactory
{
object CreateInstance(IServiceRequest request)
{
// Grab a copy of the IRepository from the container
var repository = container.GetService>();
// Get the id (this assumes that your id is an Int32)
var id = (int)request.Arguments[0];
// Return the client itself
return repository.GetById(id);
}
}
[Factory(typeof(Transaction))]
public class TransactionFactory : IFactory
{
object CreateInstance(IServiceRequest request)
{
// Note: Argument checking has been removed for brevity
var container = request.Container;
var arguments = request.Arguments;
var productId = (int)arguments[0];
var clientId = (int)arguments[1];
// Get the product and the client
var product = container.GetService(productId);
var client = container.GetService(clientId);
// Create the transaction itself
return new Transaction(product, client);
}
}
// Make this implementation a singleton
[Implements(typeof(MarginCalculator), LifecycleType.Singleton)]
public class ConcreteMarginCalculatorA : MarginCalculator
{
public override double CalculateMargin()
{
// Perform actual calculation
}
}
Once you have all that code compiled in one of your assemblies, here's all you need to do to load it into the container:
var container = new ServiceContainer();
container.LoadFrom(AppDomain.CurrentDomain.BaseDIrectory, "YourAssembly.dll");
...Now for the fun part. In order to create your transaction object with the given product and client ID, here's the call you need to make to LinFu.IOC's container:
int productId = 12345;
int clientId = 54321;
string serviceName = null;
// Not pseudocode :)
var transaction = container.GetService(serviceName, productId, clientId);
What makes this interesting is that despite the number of dependencies you might have, LinFu's IOC container will handle 90% of the boilerplate code for you so you don't have to do all this stuff on your own. The best part is that all the implementations above will all be determined/resolved at runtime.
You can practically swap implementations while the program is running, and you can even replace implementations without even recompiling your application. You can find more info here:
http://www.codeproject.com/KB/cs/LinFu_IOC.aspx
HTH :)
Here's my second take on your questions:
A: In terms of best practice, you can leave the service dependency into the domain object as long as you make sure that you're depending on an interface type. Most (if not all) containers can do that type of injection for you, and it's pretty trivial to mock out each service dependency so you can test every behavior in your concrete classes. I only recommend using abstract classes if you want to refactor out the boilerplate implementation for a particular interface implementation, such as using a base class to do your generic CRUD persistence work.
B and C:
It's good to know that this kind of functionality is available. I suppose a more important question is whether what i'm trying to do is in fact common practice and whether it's considered good practice. i.e.
Have a container resolve and inject dependencies that have been pre-populated >using a persistence framework (e.g. NHibernate) and
Have the container inject concrete implementation of abstract dependencies where the concrete implementation are determined at runtime.
Also, in IoC/DI/NHibernate terminology, does what i'm talking about, have a particular name? Is it, for example, one of the features listed in this comparison or this comparison of .net IoC frameworks? I'd like to read about whether other IoC frameworks (like Castle Windsor) include these functionalities like LinFu does but i don't know whether what i'm describing has a particular name so i don't know what to search for :)
I believe you're actually referring to the comparison posted at this link.
1) AFAIK, it's standard practice to do service injection, but the type of injection that you're referring to would be difficult to do for some of the other frameworks since you have to use domain object IDs to resolve these dependencies at run time, and not all containers support that type of dynamic resolution (aka 'contextual binding'). All things being equal (and assuming that this can be done with the other containers), the only 'best practice' that seems to apply with DI/IoC is that you must use interfaces for your service dependencies.
How these dependencies should be ultimately constructed and resolved should be completely up to you, and in your case, it really doesn't matter if you get these dependencies populated from a persistence framework as long as the container itself is able to eliminate most of the boilerplate resolution code for you.
2) Concrete service injection is standard among DI/IOC frameworks, and most of them can resolve dependencies at runtime; however, these frameworks differ on how and where that injection can be done.
FYI, the two features that you should pay attention to are Constructor Injection and Property Injection. Based on your code examples, I'd say that you'd be more inclined to use constructor injection, so you might want to keep an eye out for how each respective framework does that type of injection for you. HTH :)
Philip,
Thanks for your answer!
B and C:
It's good to know that this kind of functionality is available. I suppose a more important question is whether what i'm trying to do is in fact common practice and whether it's considered good practice. i.e.
Have a container resolve and inject dependencies that have been pre-populated using a persistence framework (e.g. NHibernate) and
Have the container inject concrete implementation of abstract dependencies where the concrete implementation are determined at runtime.
Also, in IoC/DI/NHibernate terminology, does what i'm talking about, have a particular name? Is it, for example, one of the features listed in this comparison or this comparison of .net IoC frameworks? I'd like to read about whether other IoC frameworks (like Castle Windsor) include these functionalities like LinFu does but i don't know whether what i'm describing has a particular name so i don't know what to search for :)
A:
In terms of best practice (i.e. loose coupling, testing etc...), would it be better to remove the service dependency from the domain object or leave it there?
Thanks
Matthew
According to 'Domain Driven Design', your service would be a 'Domain Service', and it's ok for the rest of your domain to call it directly or depend on it.
If you're going to use Nhibernate, check Spring.net, a very popular DI framework that provides you with DAOS, that already have a session injected on them. It also allows you to use declarative transactions (marking methods with attributes). The docs of the project are very very good.
Last but not least, and don't get me wrong, I think you are using the technology just because (I don't see that you have the NEED for DI), this is cool if you're doing it to learn stuff, but wrong in every other case.
Regards
Pablo,
Thanks for you comments.
Maybe if i elaborate a bit more on one area where i intend to use DI within the project (not only, as you say, to learn about DI but also because i think it's necessary) and then further comments can be made as to whether it's the correct place to be using DI.
As mentioned in the original post the application will make use of a MarginCalculator Service:
public abstract class MarginCalculator
{
public abstract double CalculateMargin();
}
Note: the service might be an abstract class or an Interface.
Concrete implementations (components in DI terminology?) will be as follows:
public class ConcreteMarginCalculatorA : MarginCalculator
{
private IDependencyService1 _dependencyService1;
private IDependencyService2 _dependencyService2;
// Constructor dependency injection
public ConcreteMarginCalculatorA(
IDependencyService1 dependencyService1,
IDependencyService2 dependencyService2)
{
this._dependencyService1 = dependencyService1;
this._dependencyService2 = dependencyService2;
}
public override double CalculateMargin
{
// _dependencyService1 and _dependencyService2
// required here to perform calcuation.
}
}
public class ConcreteMarginCalculatorB : MarginCalculator
{
private IDependencyService3 _dependencyService3;
private IDependencyService4 _dependencyService4;
// Constructor dependency injection
public ConcreteMarginCalculatorB(
IDependencyService3 dependencyService3,
IDependencyService4 dependencyService4)
{
this._dependencyService3 = dependencyService3;
this._dependencyService4 = dependencyService4;
}
public override double CalculateMargin
{
// _dependencyService3 and _dependencyService4
// required here to perform calcuation.
}
}
Aren't the concrete Margin Calculators and their construction a perfect example of where dependency injection should be used and how an IoC container can be used to handle the dependency injection?
I think what i'm trying to do is very similar to how DI/IoC are described in articles such as this one and this one.
Finally, i will then use a factory class, possibly with an inner/child container, in order to dynamically resolve components/implementors (ConcreteMarginCalculatorA, ConcreteMarginCalculatorB etc...) based on a parameter value. To achieve this i'm leaning toward Autofac (http://code.google.com/p/autofac/) which allows for selecting an implementor based on a parameter value (http://code.google.com/p/autofac/wiki/ComponentCreation - Section "Selection of an Implementer based on a Parameter Value"):
public class MarginCalculatorFactory
{
private readonly IContainer _factoryLevelContainer;
public MarginCalculatorFactory(IContainer mainContainer)
{
_factoryLevelContainer = mainContainer.CreateChildContainer()
_factoryLevelContainer.RegisterType<MarginCalculator, ConcreteMarginCalculatorA>("ConcMC1");
_factoryLevelContainer.RegisterType<MarginCalculator, ConcreteMarginCalculatorB>("ConcMC2");
}
public MarginCalculator CreateCalculator(string productType)
{
return _factoryLevelContainer.Resolve<MarginCalculator>(productType);
}
}
So that in the end i can do:
marginCalculatorFactory.CreateCalculator(productType);
in the client code and get a fully resolved calculator. The calculator could then in turn be dependency injected into the TransactionProcessor Service:
public class TransactionProcessor
{
private readonly MarginCalculator _marginCalculator;
private readonly Transaction _transaction;
public TransactionProcessor(MarginCalculator marginCalculator
,Transaction transaction)
{
_marginCalculator = marginCalculator;
_transaction = transaction
}
public double CalculateMargin(Transaction t)
{
return _marginCalculator.CalculateMargin(transaction);
}
}
I might be wrong as i'm new to the whole IoC/DI game but it seems to me that this is precisely the kind of scenario that Di/IoC is used for. What do others think?
Thanks
Matthew
Take a look to this post
http://fabiomaulo.blogspot.com/2008/11/entities-behavior-injection.html