I'm building a CMS and it has many extension points (Data/ContentTypes, Plugins, Macros, Themes) and some of those extensions need to register services. So far extensions only depend on 'MyProject.Core' library and it would be nice if they wouldn't be dependant on any specific IoC framework. Now I'm thinking if I should build another layer to hide IoC specific registrations. The problem is that I need some advanced functionality.
E.g. NHibernate implementation of 'Data/ContentType' services (Castle Windsor style)
container.Register(Component.For<IPageRepository>().ImplementedBy<NHPageRepository>());
container.Register(Component.For<ISessionFactory>().Instance(NHibernateHelper.CreateSessionFactory()));
container.Register(Component.For<ISession>().UsingFactoryMethod(c => c.Resolve<ISessionFactory>().OpenSession()).LifeStyle.PerWebRequest);
Third line is the "hard one". I could make an interface like
interface IMyContainer
{
Register<TService>(Func<IMyContainer,TService> factoryMethod)
Register<TService>(Func<IMyContainer,TService> factoryMethod, LifeStyle lifeStyle)
// ...
}
but "translating" this registration (my IoC abstraction)
public class NHInstaller : IInstaller
{
public void Install(IMyContainer container)
{
container.Register<ISession>(c => c.Resolve<ISessionFactory>().OpenSession(), LifeStyle.PerRequest);
}
}
to this (Windsor)
container.Register(Component.For<ISession>().UsingFactoryMethod(c => c.Resolve<ISessionFactory>().OpenSession()).LifeStyle.PerWebRequest);
could be quite hard.
So, should I try to make that abstraction? Any helpful resources?
Or should I just pick a IoC container and stick with it?
I could also make source code of an existing tool (Castle Windsor or Ninject) a part of my library, but I don't really understand those licenses. Can I do that? Can I change namespaces and class names to fit the structure of my app? I'm going to release the source code and I don't really care what the license is going to be.
It depends on what you mean by "hide." Best practice is that only one place in your application (the Composition Root) knows about the IoC container. Stick to the Hollywood Principle - avoid having multiple classes that know about the IoC container. In other words don't pass the container around; if a non-root class needs to create other objects then inject a factory into it.
If you're writing a framework and want to allow consumers to plug in their IoC container framework of choice, you could use the Common Service Locator library. That is likely overkill for most projects. (See Mark Seemann's excellent link for the reason I changed the wording).
Short answer - no, the abstraction is useless, you'd be wasting your employer's money. Use Installers to partition the registration instead.
Related
I'm pondering the design of a C# library, that will have several different high level functions. Of course, those high-level functions will be implemented using the SOLID class design principles as much as possible. As such, there will probably be classes intended for consumers to use directly on a regular basis, and "support classes" that are dependencies of those more common "end user" classes.
The question is, what is the best way to design the library so it is:
DI Agnostic - Although adding basic "support" for one or two of the common DI libraries (StructureMap, Ninject, etc) seems reasonable, I want consumers to be able to use the library with any DI framework.
Non-DI usable - If a consumer of the library is using no DI, the library should still be as easy to use as possible, reducing the amount of work a user has to do to create all these "unimportant" dependencies just to get to the "real" classes they want to use.
My current thinking is to provide a few "DI registration modules" for the common DI libraries (e.g a StructureMap registry, a Ninject module), and a set or Factory classes that are non-DI and contain the coupling to those few factories.
Thoughts?
This is actually simple to do once you understand that DI is about patterns and principles, not technology.
To design the API in a DI Container-agnostic way, follow these general principles:
Program to an interface, not an implementation
This principle is actually a quote (from memory though) from Design Patterns, but it should always be your real goal. DI is just a means to achieve that end.
Apply the Hollywood Principle
The Hollywood Principle in DI terms says: Don't call the DI Container, it'll call you.
Never directly ask for a dependency by calling a container from within your code. Ask for it implicitly by using Constructor Injection.
Use Constructor Injection
When you need a dependency, ask for it statically through the constructor:
public class Service : IService
{
private readonly ISomeDependency dep;
public Service(ISomeDependency dep)
{
if (dep == null)
{
throw new ArgumentNullException("dep");
}
this.dep = dep;
}
public ISomeDependency Dependency
{
get { return this.dep; }
}
}
Notice how the Service class guarantees its invariants. Once an instance is created, the dependency is guaranteed to be available because of the combination of the Guard Clause and the readonly keyword.
Use Abstract Factory if you need a short-lived object
Dependencies injected with Constructor Injection tend to be long-lived, but sometimes you need a short-lived object, or to construct the dependency based on a value known only at run-time.
See this for more information.
Compose only at the Last Responsible Moment
Keep objects decoupled until the very end. Normally, you can wait and wire everything up in the application's entry point. This is called the Composition Root.
More details here:
Where should I do Injection with Ninject 2+ (and how do I arrange my Modules?)
Design - Where should objects be registered when using Windsor
Simplify using a Facade
If you feel that the resulting API becomes too complex for novice users, you can always provide a few Facade classes that encapsulate common dependency combinations.
To provide a flexible Facade with a high degree of discoverability, you could consider providing Fluent Builders. Something like this:
public class MyFacade
{
private IMyDependency dep;
public MyFacade()
{
this.dep = new DefaultDependency();
}
public MyFacade WithDependency(IMyDependency dependency)
{
this.dep = dependency;
return this;
}
public Foo CreateFoo()
{
return new Foo(this.dep);
}
}
This would allow a user to create a default Foo by writing
var foo = new MyFacade().CreateFoo();
It would, however, be very discoverable that it's possible to supply a custom dependency, and you could write
var foo = new MyFacade().WithDependency(new CustomDependency()).CreateFoo();
If you imagine that the MyFacade class encapsulates a lot of different dependencies, I hope it's clear how it would provide proper defaults while still making extensibility discoverable.
FWIW, long after writing this answer, I expanded upon the concepts herein and wrote a longer blog post about DI-Friendly Libraries, and a companion post about DI-Friendly Frameworks.
The term "dependency injection" doesn't specifically have anything to do with an IoC container at all, even though you tend to see them mentioned together. It simply means that instead of writing your code like this:
public class Service
{
public Service()
{
}
public void DoSomething()
{
SqlConnection connection = new SqlConnection("some connection string");
WindowsIdentity identity = WindowsIdentity.GetCurrent();
// Do something with connection and identity variables
}
}
You write it like this:
public class Service
{
public Service(IDbConnection connection, IIdentity identity)
{
this.Connection = connection;
this.Identity = identity;
}
public void DoSomething()
{
// Do something with Connection and Identity properties
}
protected IDbConnection Connection { get; private set; }
protected IIdentity Identity { get; private set; }
}
That is, you do two things when you write your code:
Rely on interfaces instead of classes whenever you think that the implementation might need to be changed;
Instead of creating instances of these interfaces inside a class, pass them as constructor arguments (alternatively, they could be assigned to public properties; the former is constructor injection, the latter is property injection).
None of this presupposes the existence of any DI library, and it doesn't really make the code any more difficult to write without one.
If you're looking for an example of this, look no further than the .NET Framework itself:
List<T> implements IList<T>. If you design your class to use IList<T> (or IEnumerable<T>), you can take advantage of concepts like lazy-loading, as Linq to SQL, Linq to Entities, and NHibernate all do behind the scenes, usually through property injection. Some framework classes actually accept an IList<T> as a constructor argument, such as BindingList<T>, which is used for several data binding features.
Linq to SQL and EF are built entirely around the IDbConnection and related interfaces, which can be passed in via the public constructors. You don't need to use them, though; the default constructors work just fine with a connection string sitting in a configuration file somewhere.
If you ever work on WinForms components you deal with "services", like INameCreationService or IExtenderProviderService. You don't even really know what what the concrete classes are. .NET actually has its own IoC container, IContainer, which gets used for this, and the Component class has a GetService method which is the actual service locator. Of course, nothing prevents you from using any or all of these interfaces without the IContainer or that particular locator. The services themselves are only loosely-coupled with the container.
Contracts in WCF are built entirely around interfaces. The actual concrete service class is usually referenced by name in a configuration file, which is essentially DI. Many people don't realize this but it is entirely possible to swap out this configuration system with another IoC container. Perhaps more interestingly, the service behaviors are all instances of IServiceBehavior which can be added later. Again, you could easily wire this into an IoC container and have it pick the relevant behaviors, but the feature is completely usable without one.
And so on and so forth. You'll find DI all over the place in .NET, it's just that normally it's done so seamlessly that you don't even think of it as DI.
If you want to design your DI-enabled library for maximum usability then the best suggestion is probably to supply your own default IoC implementation using a lightweight container. IContainer is a great choice for this because it's a part of the .NET Framework itself.
EDIT 2015: time has passed, I realize now that this whole thing was a huge mistake. IoC containers are terrible and DI is a very poor way to deal with side effects. Effectively, all of the answers here (and the question itself) are to be avoided. Simply be aware of side effects, separate them from pure code, and everything else either falls into place or is irrelevant and unnecessary complexity.
Original answer follows:
I had to face this same decision while developing SolrNet. I started with the goal of being DI-friendly and container-agnostic, but as I added more and more internal components, the internal factories quickly became unmanageable and the resulting library was inflexible.
I ended up writing my own very simple embedded IoC container while also providing a Windsor facility and a Ninject module. Integrating the library with other containers is just a matter of properly wiring the components, so I could easily integrate it with Autofac, Unity, StructureMap, whatever.
The downside of this is that I lost the ability to just new up the service. I also took a dependency on CommonServiceLocator which I could have avoided (I might refactor it out in the future) to make the embedded container easier to implement.
More details in this blog post.
MassTransit seems to rely on something similar. It has an IObjectBuilder interface which is really CommonServiceLocator's IServiceLocator with a couple more methods, then it implements this for each container, i.e. NinjectObjectBuilder and a regular module/facility, i.e. MassTransitModule. Then it relies on IObjectBuilder to instantiate what it needs. This is a valid approach of course, but personally I don't like it very much since it's actually passing around the container too much, using it as a service locator.
MonoRail implements its own container as well, which implements good old IServiceProvider. This container is used throughout this framework through an interface that exposes well-known services. To get the concrete container, it has a built-in service provider locator. The Windsor facility points this service provider locator to Windsor, making it the selected service provider.
Bottom line: there is no perfect solution. As with any design decision, this issue demands a balance between flexibility, maintainability and convenience.
What I would do is design my library in a DI container agnostic way to limit the dependency on the container as much as possible. This allows to swap out on DI container for another if need be.
Then expose the layer above the DI logic to the users of the library so that they can use whatever framework you chose through your interface. This way they can still use DI functionality that you exposed and they are free to use any other framework for their own purposes.
Allowing the users of the library to plug their own DI framework seems a bit wrong to me as it dramatically increases amount of maintenance. This also then becomes more of a plugin environment than straight DI.
The short question is:
Given a library warrants using a particular IOC container for its internals, when an application consumes that library, given the app warrants using an IOC container for wiring its dependencies, given if the the two containers are different, how can they play well together?
The scenario is, the application has classes defined that depend on types from the library. So when the application container attempts to build such a class, it needs to know how to resolve the type that lives in the library.
Here's the long winded question:
This question does seem to have been asked in different shapes and form before on SO, but I can't seem to find the answer I need so I am going to have a go at it with a hypothetical _over_simplified_ concrete example.
We want to write a library for logging that users can include as a package in their solution to get logging functionality out of the box.
The public interfaces the library exposes are..
public interface ILogger {}
public interface ITarget {}
Concrete implementations are
internal class Logger: ILogger { public Logger(ITarget target) {}}
internal class FileTarget : ITarget {}
Requirements are if the user includes our package and defines a class with a property of type ILogger or has a ctor argument of type ILogger then our library is responsible for injecting a concrete implementation for that interface into the user defined class. By default that injected logger will go to the file system for logging because the default implementation of an ITarget injected into the ILogger implementation is a FileTarget by our library.
If the user decides to write a class implementing the ITarget interface then our library will use that to inject into the Logger class and not use its default FileTarget implementation.
SO what I wish to demonstrate, is their is a bi-directional dependency here.
Our library depends on the user's assemblies, since it needs to scan the user's assemblies to load any extension points (i.e. an ITarget implementation) and inject those into its own objects ahead of any default implementations.
The user's assemblies depends on the library, since if the user chooses to define a class with an ILogger interface as a dependency, then that user object should get a concrete reference to that interface provided at runtime by our library.
The easy solution is if the user and our library are both using the same IOC container, then problem is solved. But this is a strong assumption. What I wish to do is
Use an IOC container with the library that caters best to the library's requirement, in my case its Ninject.
At run time somehow provide a mechanism for the user to call via some API into my library that will ensure Ninject is fired up and it scans the user's assemblies, and wires everything taking into account all extension points.
So far so good, its perfectly achievable, but here comes the tricky part.
if the user is also using Ninject, then problem automatically solved, since Ninject already knows how to resolve Interfaces living in our library. But what if the user decides to use his/her choice of IOC container?
I almost want to define some sort of child container functionality in the library with an interface like such
public interface IDependencyResolvingModule { T Get<T>(); []T GetAll<T>(); }
and provide an implementation that uses our library's choice of container (i.e. Ninect) to resolve the type requested in the two methods define above.
I want the user's IOC container to have some functionality where if it can't resolve a dependency (i.e. an ILogger), it should hook into the IDependencyResolvingModule implementation and ask for the dependency.
This way our library gets to use its choice of IOC Container, and the user's code has a way to resolve dependencies that its IOC container has no clue about. Wouldn't this solution work if IOC containers out there some how provided functionality to register singleton instances of any IDependencyResolverModules found in assemblies in the executing assembly's dir and when they can't resolve a type, ask any of the singleton modules?
But barring a solution that requires every other IOC container to accommodate, how else can this be solved? SO the problem in a few lines is, when a third party assembly chooses to use an IOC container for its internals, what is an easy solution such that this library can simply provide a mechanism for an IOC container sitting outside to hook into and resolve dependencies that live in the library.
I see few possible approaches here:
Write default registrator for all of the popular IoC containers. Each of them should be placed in the separate assembly. Then developer can choose the one he needs and configure his container with it.
Define your own factory abstraction and write default implementation that will return the default logger. Let developer to substitute implementation of that factory. For example, with adapter for his favorite container. This approach is most container-agnostic, because developer can just use the default factory implementation. But this way has nothing to do with auto-wiring.
The lazy variation of the first approach. Write small manual about configuring a container to work with default implementations. Then developer could configure the container himself.
Combine all previous solutions to satisfy every developer. :)
EDIT: added example of integration of two containers
var allPublicInterfacesFromLibrary = typeof(AnyLibraryType)
.Assembly.GetTypes()
.Where(t => t.IsInterface && t.IsPublic);
foreach (var libraryInterface in allPublicInterfacesFromLibrary)
{
var local = libraryInterface; //to prevent closure
applicationContainer.Register(
Component.For(libraryInterface)
//delegate resolving
.UsingFactoryMethod(k => libraryContainer.Resolve(local))
//delegate lifetime management
.LifestyleTransient()
);
}
In which scenario should we use which? How to decide on which one to choose? And under which circumstances would we choose to use both together?
I have previously worked with Unity Container (unity-container).
Tricky question - since the two do indeed overlap to a certain degree.
I would say this:
use any useful IoC if you're primarily concerned about dependency injection for the sake of decoupling your components, e.g. for the ability to be able to inject a mock instead (for testing)
use MEF especially if you're more into being extensible, e.g. be able to "load all assemblies from that directory that export a certain interface", and if you need to be extensible and open for third parties (like Visual Studio: offer a public API so others can write an extension for your app). This is where MEF really shines
For MEF and Unity, there's also the MEF and Unity Integration Layer to combine the strengths of both tools together.
I would also recommend you check out Ayende's excellent blog post on what differentiates MEF from an IoC.
MEF shines when you have 3rd parties writing plug-ins, that implement interfaces and you wish to be able to version your interface without breaking the 3rd party plug in you can’t recompile. In exchange MEF is more complex than a raw IoC.
So I would say IoC if everything is compiled as part of the same build system, and MEF if you need to cope with add-ins you can’t recompile yourself.
Glen Block (former Product Manager of MEF) has covered this pretty well on his blog:
Should I use MEF for my general IoC needs?
Should I use MEF with an IoC container? - Part 1
I heard a great explanation of this (apologies to the author, I've forgotten who it was): At a very high level, IoC is good when you want one thing for a given interface, MEF is good for when you want all things from a given interface.
For instance in IoC you want to return a specific single concrete class for an interface:
For<ICarFactory>().Use<CarFactory>();
Whenever you want to use a ICanFactory you will get a CarFactory.
MEF is good for saying give me all the car factories:
CheapCarFactory : ICarFactory
FamilyCarFactory : ICarFactory
LuxuryCarFactory : ICarFactory
Etc.
I'm pondering the design of a C# library, that will have several different high level functions. Of course, those high-level functions will be implemented using the SOLID class design principles as much as possible. As such, there will probably be classes intended for consumers to use directly on a regular basis, and "support classes" that are dependencies of those more common "end user" classes.
The question is, what is the best way to design the library so it is:
DI Agnostic - Although adding basic "support" for one or two of the common DI libraries (StructureMap, Ninject, etc) seems reasonable, I want consumers to be able to use the library with any DI framework.
Non-DI usable - If a consumer of the library is using no DI, the library should still be as easy to use as possible, reducing the amount of work a user has to do to create all these "unimportant" dependencies just to get to the "real" classes they want to use.
My current thinking is to provide a few "DI registration modules" for the common DI libraries (e.g a StructureMap registry, a Ninject module), and a set or Factory classes that are non-DI and contain the coupling to those few factories.
Thoughts?
This is actually simple to do once you understand that DI is about patterns and principles, not technology.
To design the API in a DI Container-agnostic way, follow these general principles:
Program to an interface, not an implementation
This principle is actually a quote (from memory though) from Design Patterns, but it should always be your real goal. DI is just a means to achieve that end.
Apply the Hollywood Principle
The Hollywood Principle in DI terms says: Don't call the DI Container, it'll call you.
Never directly ask for a dependency by calling a container from within your code. Ask for it implicitly by using Constructor Injection.
Use Constructor Injection
When you need a dependency, ask for it statically through the constructor:
public class Service : IService
{
private readonly ISomeDependency dep;
public Service(ISomeDependency dep)
{
if (dep == null)
{
throw new ArgumentNullException("dep");
}
this.dep = dep;
}
public ISomeDependency Dependency
{
get { return this.dep; }
}
}
Notice how the Service class guarantees its invariants. Once an instance is created, the dependency is guaranteed to be available because of the combination of the Guard Clause and the readonly keyword.
Use Abstract Factory if you need a short-lived object
Dependencies injected with Constructor Injection tend to be long-lived, but sometimes you need a short-lived object, or to construct the dependency based on a value known only at run-time.
See this for more information.
Compose only at the Last Responsible Moment
Keep objects decoupled until the very end. Normally, you can wait and wire everything up in the application's entry point. This is called the Composition Root.
More details here:
Where should I do Injection with Ninject 2+ (and how do I arrange my Modules?)
Design - Where should objects be registered when using Windsor
Simplify using a Facade
If you feel that the resulting API becomes too complex for novice users, you can always provide a few Facade classes that encapsulate common dependency combinations.
To provide a flexible Facade with a high degree of discoverability, you could consider providing Fluent Builders. Something like this:
public class MyFacade
{
private IMyDependency dep;
public MyFacade()
{
this.dep = new DefaultDependency();
}
public MyFacade WithDependency(IMyDependency dependency)
{
this.dep = dependency;
return this;
}
public Foo CreateFoo()
{
return new Foo(this.dep);
}
}
This would allow a user to create a default Foo by writing
var foo = new MyFacade().CreateFoo();
It would, however, be very discoverable that it's possible to supply a custom dependency, and you could write
var foo = new MyFacade().WithDependency(new CustomDependency()).CreateFoo();
If you imagine that the MyFacade class encapsulates a lot of different dependencies, I hope it's clear how it would provide proper defaults while still making extensibility discoverable.
FWIW, long after writing this answer, I expanded upon the concepts herein and wrote a longer blog post about DI-Friendly Libraries, and a companion post about DI-Friendly Frameworks.
The term "dependency injection" doesn't specifically have anything to do with an IoC container at all, even though you tend to see them mentioned together. It simply means that instead of writing your code like this:
public class Service
{
public Service()
{
}
public void DoSomething()
{
SqlConnection connection = new SqlConnection("some connection string");
WindowsIdentity identity = WindowsIdentity.GetCurrent();
// Do something with connection and identity variables
}
}
You write it like this:
public class Service
{
public Service(IDbConnection connection, IIdentity identity)
{
this.Connection = connection;
this.Identity = identity;
}
public void DoSomething()
{
// Do something with Connection and Identity properties
}
protected IDbConnection Connection { get; private set; }
protected IIdentity Identity { get; private set; }
}
That is, you do two things when you write your code:
Rely on interfaces instead of classes whenever you think that the implementation might need to be changed;
Instead of creating instances of these interfaces inside a class, pass them as constructor arguments (alternatively, they could be assigned to public properties; the former is constructor injection, the latter is property injection).
None of this presupposes the existence of any DI library, and it doesn't really make the code any more difficult to write without one.
If you're looking for an example of this, look no further than the .NET Framework itself:
List<T> implements IList<T>. If you design your class to use IList<T> (or IEnumerable<T>), you can take advantage of concepts like lazy-loading, as Linq to SQL, Linq to Entities, and NHibernate all do behind the scenes, usually through property injection. Some framework classes actually accept an IList<T> as a constructor argument, such as BindingList<T>, which is used for several data binding features.
Linq to SQL and EF are built entirely around the IDbConnection and related interfaces, which can be passed in via the public constructors. You don't need to use them, though; the default constructors work just fine with a connection string sitting in a configuration file somewhere.
If you ever work on WinForms components you deal with "services", like INameCreationService or IExtenderProviderService. You don't even really know what what the concrete classes are. .NET actually has its own IoC container, IContainer, which gets used for this, and the Component class has a GetService method which is the actual service locator. Of course, nothing prevents you from using any or all of these interfaces without the IContainer or that particular locator. The services themselves are only loosely-coupled with the container.
Contracts in WCF are built entirely around interfaces. The actual concrete service class is usually referenced by name in a configuration file, which is essentially DI. Many people don't realize this but it is entirely possible to swap out this configuration system with another IoC container. Perhaps more interestingly, the service behaviors are all instances of IServiceBehavior which can be added later. Again, you could easily wire this into an IoC container and have it pick the relevant behaviors, but the feature is completely usable without one.
And so on and so forth. You'll find DI all over the place in .NET, it's just that normally it's done so seamlessly that you don't even think of it as DI.
If you want to design your DI-enabled library for maximum usability then the best suggestion is probably to supply your own default IoC implementation using a lightweight container. IContainer is a great choice for this because it's a part of the .NET Framework itself.
EDIT 2015: time has passed, I realize now that this whole thing was a huge mistake. IoC containers are terrible and DI is a very poor way to deal with side effects. Effectively, all of the answers here (and the question itself) are to be avoided. Simply be aware of side effects, separate them from pure code, and everything else either falls into place or is irrelevant and unnecessary complexity.
Original answer follows:
I had to face this same decision while developing SolrNet. I started with the goal of being DI-friendly and container-agnostic, but as I added more and more internal components, the internal factories quickly became unmanageable and the resulting library was inflexible.
I ended up writing my own very simple embedded IoC container while also providing a Windsor facility and a Ninject module. Integrating the library with other containers is just a matter of properly wiring the components, so I could easily integrate it with Autofac, Unity, StructureMap, whatever.
The downside of this is that I lost the ability to just new up the service. I also took a dependency on CommonServiceLocator which I could have avoided (I might refactor it out in the future) to make the embedded container easier to implement.
More details in this blog post.
MassTransit seems to rely on something similar. It has an IObjectBuilder interface which is really CommonServiceLocator's IServiceLocator with a couple more methods, then it implements this for each container, i.e. NinjectObjectBuilder and a regular module/facility, i.e. MassTransitModule. Then it relies on IObjectBuilder to instantiate what it needs. This is a valid approach of course, but personally I don't like it very much since it's actually passing around the container too much, using it as a service locator.
MonoRail implements its own container as well, which implements good old IServiceProvider. This container is used throughout this framework through an interface that exposes well-known services. To get the concrete container, it has a built-in service provider locator. The Windsor facility points this service provider locator to Windsor, making it the selected service provider.
Bottom line: there is no perfect solution. As with any design decision, this issue demands a balance between flexibility, maintainability and convenience.
What I would do is design my library in a DI container agnostic way to limit the dependency on the container as much as possible. This allows to swap out on DI container for another if need be.
Then expose the layer above the DI logic to the users of the library so that they can use whatever framework you chose through your interface. This way they can still use DI functionality that you exposed and they are free to use any other framework for their own purposes.
Allowing the users of the library to plug their own DI framework seems a bit wrong to me as it dramatically increases amount of maintenance. This also then becomes more of a plugin environment than straight DI.
I'm writing a new .NET library for internal use at my company that will use IoC through Dependency Injection. Naturally, this library will be much easier to use if we use an IoC Container to resolve instances.
However, the code that will be making calls into this library does NOT currently use Dependency Injection of any sort, and refactoring the legacy code to use DI is out of scope for my project. So, what's the best way to start using a Container in this legacy code to get instances from my new library?
If possible, I'd like to keep from littering said legacy code with hard references to whichever IoC container I choose. Since I'm relatively new to DI, it's somewhat likely that we'll change our mind on which Container we want to use at some point.
If I wrap my container in something like the CommonServiceLocator library on CodePlex, would that be a reasonable approach?
What have other folks done?
You can use a facade / proxy pattern to hide the DI Container from your legacy container. You are essentially hardwiring your legacy to a custom class that you implement which will know about the DI container. Now if you modify your DI you update your facades not your legacy code.
I've not done a lot of research into Common Service Locator but it's premise might be a good solution. You might want to tie your facade to the CSL, this will hide the DI concept completly from your legacy code.
As I understand your question, you want to invoke DI-enabled code from legacy code.
The best option is to keep the new library DI Friendly, but container-agnostic.
Doing this, you can provide a simple Facade the legacy code can use. No need for the legacy app to use any DI Container, and no need for the Common Service Locator.