We have a landscape with 15 solutions, where each solution contains many projects of its own. All solutions however, share some common project called "Model". Since each solution however, wires its own object graphs, this causes the registrations for the Model project to be duplicated 15 times.
What's the best way to prevent this duplication?
Example:
Solution-A
Model
public class Account
{
public Account()
{
var a=Resolve<IEmailer>();
}
}
The addition of above code in constructor forces me to register the dependencies in all start-up projects of the solutions if they refer the above class. Some solution need Account class but not IEmailer but still it need to inject IEmailer in that solution.
Registering everything in the start-up project is actually a good thing. This common place is called the Composition Root and it allows you to minimize the number of references between your projects, as explained clearly here.
Another thing you should prevent is letting your code (anything except your composition root) depend on the DI library or an abstraction over your DI library. So instead of calling Resolve from inside your constructors, let any dependency a class has be injected into the constructor of that class. Example:
public class Account
{
private readonly IEmailer emailer;
public Account(IEmailer emailer)
{
this.emailer = emailer;
}
}
This has many advantages over calling back into the container from within your code.
Do note though that your container is meant to build up object graphs of your services. If Account is an entity, resolving that from the container is not a usual and advised thing to do.
About the multiple-solution problem you're having: Since the shared project you're using, it might be good to prevent referencing this as a project, but make this an independent project with its own release cycle. Other projects can in that case depend on the assembly that you publish (for instance using your own local NuGet server).
But besides this, since this is a reusable project, make sure that assembly becomes a DI friendly library. If any bootstrapping should be done, and you want to prevent repeating this across solutions, create a separate bootstrapping-project. This bootstrapping-project refers to the reusable library and it references your Unity container. This way your library still stays completely independent to the used DI library, while you prevent duplicating bootstrapping logic throughout the solutions.
Related
(Related to this question, EF4: Why does proxy creation have to be enabled when lazy loading is enabled?).
I'm new to DI, so bear with me. I understand that the container is in charge of instantiating all of my registered types but in order to do so it requires a reference to all of the DLLs in my solution and their references.
If I weren't using a DI container, I wouldn't have to reference the EntityFramework library in my MVC3 app, only my business layer, which would reference my DAL/Repo layer.
I know that at the end of the day all DLLs are included in the bin folder but my problem is having to reference it explicitly via "add reference" in VS in order to be able to publish a WAP with all necessary files.
If I wasn't using a DI container, I wouldn't have to reference EntityFramework library in my MVC3 app, only my business layer which would reference my DAL/Repo layer.
Yes, that's exactly the situation DI works so hard to avoid :)
With tightly coupled code, each library may only have a few references, but these again have other references, creating a deep graph of dependencies, like this:
Because the dependency graph is deep, it means that most libraries drag along a lot of other dependencies - e.g. in the diagram, Library C drags along Library H, Library E, Library J, Library M, Library K and Library N. This makes it harder to reuse each library independently from the rest - for example in unit testing.
However, in a loosely coupled application, by moving all the references to the Composition Root, the dependency graph is severely flattened:
As illustrated by the green color, it's now possible to reuse Library C without dragging along any unwanted dependencies.
However, all that said, with many DI Containers, you don't have to add hard references to all required libraries. Instead, you can use late binding either in the form of convention-based assembly-scanning (preferred) or XML configuration.
When you do that, however, you must remember to copy the assemblies to the application's bin folder, because that no longer happens automatically. Personally, I rarely find it worth that extra effort.
A more elaborate version of this answer can be found in this excerpt from my book Dependency Injection, Principles, Practices, Patterns.
If I wasn't using an DI container, I wouldn't have to reference
EntityFramework library in my MVC3 app
Even when using a DI container, you don't have to let your MVC3 project reference Entity Framework, but you (implicitly) choose to do this by implementing the Composition Root (the startup path where you compose your object graphs) inside your MVC3 project. If you are very strict about protecting your architectural boundaries using assemblies, you can move your presentation logic to a different project.
When you move all MVC related logic (controllers, etc) from the startup project to a class library, it allows this presentation layer assembly to stay disconnected from the rest of the application. Your web application project itself will become a very thin shell with the required startup logic. The web application project will be the Composition Root that references all other assemblies.
Extracting the presentation logic to a class library can complicate things when working with MVC. It will be harder to wire everything up, since controllers are not in the startup project (while views, images, CSS files, must likely stay in the startup project). This is probably doable but will take more time to set up.
Because of the downsides I generally advice to just keep the Composition Root in the web project. Many developers don’t want their MVC assembly to depend on the DAL assembly, but that should not be a problem. Don't forget that assemblies are a deployment artifact; you split code into multiple assemblies to allow code to be deployed separately. An architectural layer on the other hand is a logical artifact. It's very well possible (and common) to have multiple layers in the same assembly.
In this case you'll end up having the Composition Root (layer) and the Presentation Layer in the same web application project (thus in the same assembly). And even though that assembly references the assembly containing the DAL, the Presentation Layer still does not reference the DAL—this is a big distinction.
Of course, when you do this, you're losing the ability for the compiler to check this architectural rule at compile time. But most architectural rules actually can't be checked by the compiler. In case you're afraid your team won't follow the architectural rules, I'd advise introducing code reviews, which is an important practice to increase code quality, consistency and improve the skills of a team. You can also use tools like NDepend (which is commercial), which help you verifying your architectural rules. When you integrate NDepend with your build process, it can warn you when somebody checked code in that violates such architectural rule.
You can read a more elaborate discussion on how the Composition Root works in chapter 4 of my book Dependency Injection, Principles, Practices, Patterns.
If I wasn't using an DI container, I wouldn't have to reference
EntityFramework library in my MVC3 app, only my business layer which
would reference my DAL/Repo layer.
You can create a seperate project called "DependencyResolver".
In this project you have to reference all your libraries.
Now the UI Layer doesn't need NHibernate/EF or any other not UI relevant library except of Castle Windsor to be referenced.
If you want to hide Castle Windsor and DependencyResolver from your UI layer you could write an HttpModule which calls the IoC registry stuff.
I have only an example for StructureMap:
public class DependencyRegistrarModule : IHttpModule
{
private static bool _dependenciesRegistered;
private static readonly object Lock = new object();
public void Init(HttpApplication context)
{
context.BeginRequest += (sender, args) => EnsureDependenciesRegistered();
}
public void Dispose() { }
private static void EnsureDependenciesRegistered()
{
if (!_dependenciesRegistered)
{
lock (Lock)
{
if (!_dependenciesRegistered)
{
ObjectFactory.ResetDefaults();
// Register all you dependencies here
ObjectFactory.Initialize(x => x.AddRegistry(new DependencyRegistry()));
new InitiailizeDefaultFactories().Configure();
_dependenciesRegistered = true;
}
}
}
}
}
public class InitiailizeDefaultFactories
{
public void Configure()
{
StructureMapControllerFactory.GetController = type => ObjectFactory.GetInstance(type);
...
}
}
The DefaultControllerFactory doesn't use the IoC container directly, but it delegates to IoC container methods.
public class StructureMapControllerFactory : DefaultControllerFactory
{
public static Func<Type, object> GetController = type =>
{
throw new InvalidOperationException("The dependency callback for the StructureMapControllerFactory is not configured!");
};
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
return base.GetControllerInstance(requestContext, controllerType);
}
return GetController(controllerType) as Controller;
}
}
The GetController delegate is set in a StructureMap Registry (in Windsor it should be an Installer).
There is a dependency : if an object instantiate another object.
There is no dependency : if an object expects an abstraction (contructor injection, method injection ...)
Assembly References (referencing dll, webservices..) are independant from the dependency concept, because to resolve an abstraction and be able to compile the code, the layer must reference it.
I'm working with Castle Windsor as an IoC. I'm looking at a bit of code written by a team member and I am trying to figure out what the best practice here would be. Something rings odd to me about the way this was written, but I don't have the experience to say what should be done.
There are two Castle configs (which is my first gripe, but to give a benefit of the doubt, let's say this is okay). Let's say: cfgMain and cfgSub.
There is a main class which is responsible for setting up the application and causing it to run. (It can be a class with a Main() or a Global.asax, doesn't matter). Let's say: MainClass.
There is also a DependentClass.
MainClass instantiates a CastleContainer and installs cfgMain into it, then Resolves DependentClass.
DependentClass creates another CastleContainer and installs cfgSub in it. This is what I have a problem with
It seems like having a hardcoded path to a config inside of a class which itself is created via IoC is a recipe for disaster. It also makes it very hard to unit test.
Call to action: What's the best practice here? Should all the configs be merged? What if there's a reason (read: need) to separate them?
Without the information on why there are two configurations, it is impossible to judge that.
But assuming there is a reason, both classes sound to be parts of the Composite Root, a place near the start of the application that wires up all container dependencies. The main class is the composition root for the first configuration, the dependant class for the second configuration. There is still nothing wrong.
I would say that resolving the dependant class with the first container makes no sense - the composite root is a concrete class and there is no reason to replace it. However, there could be another reason the container is used to instantiate it - dependencies. If the dependant class itself depends on other services, resolving it with the main configuration sounds like the only way to resolve these dependencies.
Ultimately, with no other information, I would say that (with all these assumptions) what you describe could possibly make sense.
However, I strongly recommend to review the need of two separate configurations and two separate composite roots. Sounds overcomplicated.
I'm currently using Ninject to handle DI on a C#/.Net/MVC application. When I trace the creation of instances of my services, I find that services are called and constructed quite a lot during a the life cycle, so I'm having to instantiate services and cache them, and then check for cached services before instantiating another. The constructors are sometimes quite heavy).
To me this seems ridiculous, as the services do not need unique constructor arguments, so instantiating them once is enough for the entire application scope.
What I've done as a quick alternative (just for proof-of-concept for now to see if it even works) is...
Created a static class (called AppServices) with all my service interfaces as it's properties.
Given this class an Init() method that instantiates a direct implementation of each service interface from my service library. This mimics binding them to a kernel if I was using Ninject (or other DI handler).
E.g.
public static class AppServices(){
public IMyService MyService;
public IMyOtherService MyOtherService;
public Init(){
MyService = new MyLib.MyService();
MyOtherService = new MyLib.MyOtherService();
}
}
On App_Start I call the Init() method to create a list of globally accessible services that are only instantiated once.
From then on, every time I need an instance of a service, I get it from AppServices. This way I don't have to keep constructing new instances that I don't need.
E.g.
var IMyService _myService = AppServices.MyService;
This works fine and I haven't had ANY issues arise yet. My problem is that this seems way too simple. It is only a few lines of code, creating a static class in application scope. Being as it does exactly what I would need Ninject to do, but in (what seems to me for my purposes) a much cleaner and performance-saving way, why do I need Ninject? I mean, these complicated dependency injection handlers are created for a reason right? There must be something wrong with my "simple" interpretation of DI, I just can't see it.
Can any one tell me why creating a global static container for my service instances is a bad idea, and maybe explain exactly what make Ninject (or any other DI handler) so necessary. I understand the concepts of DI so please don't try and explain what makes it so great. I know. I want to know exactly what it does under the hood that is so different to my App_Start method.
Thanks
Your question needs to be divided into two questions:
Is it really wrong to use the singleton pattern instead to inject dependencies?
Why do I need an IoC container?
1)
There are many reasons why you should not use the singleton pattern. Here are some of the major ones:
Testability
Yes you can test with static instances. But you can't test Isolated (FIRST). I have seen projects that searched a long time why tests start failing for no obvious reason until they realized that it is due to tests that were run in a different order. When you had that problem once you will always want your tests to be as isolated as possible. Static values couples tests.
This gets even worse when you also do integration/spec testing additional to unittesting.
Reusability
You can't simply reuse your components in other projects. Other projects will have to use that concept as well even if they might decide to use an IoC container.
Or you can't create another instance of your component with different dependencies. The components dependencies will be hard wired to the instances in your AppServices. You will have to change the components implementation to use different dependencies.
2) Doing DI does not mean that you have to use any IoC container. You can implement your own IDependencyResolver that creates your controllers manually and injects the same instance of your services wherever they are required. IoC containers use some performance but they simplyfy the creation of your object trees. You will have to decide yourself what matters more performance or simpler creation of your controllers.
I am brand new to IoC and thus have been following the examples provided by Jeffery Palermo in his posts at http://jeffreypalermo.com/blog/the-onion-architecture-part-1/ and in his book hosted here https://github.com/jeffreypalermo/mvc2inaction/tree/master/manuscript/Chapter23
Most important to note is that I am not using a pre-rolled IoC container, mostly because I want to understand all the moving parts.
However, I am creating a windows service rather than an ASP.NET MVC webapp so I am little bogged down on the startup portion. Specifically, in the web.config he registers an IHttpModule implementation INSIDE the infrastructure project as the startup module and then uses a post-build event to copy the necessary dlls into the website directory to get around having a direct dependency in the web project itself.
I don't think I have this type of luxury in a true windows service, so how do I achieve something similar, should I have a small startup project which has dependencies to both the Infrastructure and Core, or is there another method to get around the compile-time restrictions of the windows service?
Thanks in advance.
Based on the tags of this question (c#) I'm assuming that you'll implement the Windows Service by deriving from ServiceBase. If so, the OnStart method will be your Composition Root - this is where you compose the application's object graph. After you've composed the object graph, composition is over and the composed object graph takes over.
In OnStop you can decommission the object graph again.
There's nothing stopping you from implementing the various components of the resolved object graph in separate assemblies. That's what I would do.
I think you missunderstood the role of an IoC framework.
To answer your question
but doesn't the reference imply dependency?
Yes it does, but on an other level. IoC is about dependencies between classes.
Instead of using new Something() in your class you provide a constructor which requires all dependent interfaces. This way the class has no control which implementation is passed to it. This is inversion of control. The IoC Container is just an aid to help managing the dependencies in a nice manner.
Say you have a ICustomerNotificationService interface with an implementation like
public class MailNotificationService : INotificationService
{
IMailerService _mailer;
ICustomerRepository _customerRepo;
IOrderRepository _orderRepo;
public MailNotificationService(IMailerService mailer,
ICustomerRepository customerRepo,
IOrderRepository oderRepo)
{
// set fields...
}
public void Notify(int customerId, int productId)
{
// load customer and order, format mail and send.
}
}
So if your application requests an instance of ICustomerNotificationServcie the container figures out which concrete implementations to take and tries to satisfy all dependencies the requested class has.
The advantage is that you can easily configure all dependencies in your bootstrapping logic and be able to change the behaviour of your application very easily.
For example when testing you start the application with an IMailerService implementation which writes the mails to a file and in production mode a real mail service is wired. This would not be possible if you newed up say a MailerService in your constructor instead of taking it as a parameter.
A good IoC container can handle much more, for you like lifetime management, singletons, scanning assemblies for Types you want to register and many more. We based our entire plugin system on Structure Map for example.
You may want to take a look at this blog article and its second part.
I've recently become a heavy user of Autofac's OwnedInstances feature. For example, I use it to provide a factory for creating a Unit of Work for my database, which means my classes which depend on the UnitOfWork factory are asking for objects of type :
Func<Owned<IUnitOfWork>>
This is incredibly useful--great for keeping IDisposable out of my interfaces--but it comes with a price: since Owned<> is part of the Autofac assembly, I have to reference Autofac in each of my projects that knows about Owned<>, and put "using Autofac.Features.OwnedInstances" in every code file.
Func<> has the great benefit of being built into the .NET framework, so I have no doubts that it's fine to use Func as a universal factory wrapper. But Owned<> is in the Autofac assembly, and every time I use it I'm creating a hard reference to Autofac (even when my only reference to Autofac is an Owned<> type in an interface method argument).
My question is: is this a bad thing? Will this start to bite me back in some way that I'm not yet taking into account? Sometimes I'll have a project which is referenced by many other projects, and so naturally I need to keep its dependencies as close as possible to zero; am I doing evil by passing a Func<Owned<IUnitOfWork>> (which is effectively a database transaction provider) into methods in these interfaces (which would otherwise be autofac-agnostic)?
Perhaps if Owned<> was a built-in .NET type, this whole dilemma would go away? (Should I even hold my breath for that to happen?)
I agree with #steinar, I would consider Autofac as yet another 3rd party dll that supports your project. Your system depends on it, why should you restrict yourself from referencing it? I would be more conserned if ILifetimeScope or IComponentContext were sprinkled around your code.
That said, I feel your consern. After all, a DI container should work behind the scenes and not "spill" into the code. But we could easily create a wrapper and an interface to hide even the Owned<T>. Consider the following interface and implementation:
public interface IOwned<out T> : IDisposable
{
T Value { get; }
}
public class OwnedWrapper<T> : Disposable, IOwned<T>
{
private readonly Owned<T> _ownedValue;
public OwnedWrapper(Owned<T> ownedValue)
{
_ownedValue = ownedValue;
}
public T Value { get { return _ownedValue.Value; } }
protected override void Dispose(bool disposing)
{
if (disposing)
_ownedValue.Dispose();
}
}
The registration could be done, either using a registration source or a builder, e.g. like this:
var cb = new ContainerBuilder();
cb.RegisterGeneric(typeof (OwnedWrapper<>)).As(typeof (IOwned<>)).ExternallyOwned();
cb.RegisterType<SomeService>();
var c = cb.Build();
You can now resolve as usual:
using (var myOwned = c.Resolve<IOwned<SomeService>>())
{
var service = myOwned.Value;
}
You could place this interface in a common namespace in your system for easy inclusion.
Both the Owned<T> and OwnedWrapper<T> are now hidden from your code, only IOwned<T> is exposed. Should requirements change and you need to replace Autofac with another DI container there's a lot less friction with this approach.
I would say that it's fine to reference a well defined set of core 3rd party DLLs in every project of an "enterprise application" solution (or any application that needs flexibility). I see nothing wrong with having a dependency on at least the following in every project that needs it:
A logging framework (e.g. log4net)
Some IoC container (e.g. Autofac)
The fact that these aren't part of the core .NET framework shouldn't stop us from using them as liberally.
The only possible negatives I can see are relatively minor compared to the possible benefits:
This may make the application harder to understand for the average programmer
You could have version compatibility problems in the future which you wouldn't encounter if you were just using the .NET framework
There is an obvious but minor overhead with adding all of these references to every solution
Perhaps if Owned<> was a built-in .NET
type, this whole dilemma would go
away? (Should I even hold my breath
for that to happen?)
It will become a built-in .NET type: ExportLifeTimeContext<T>. Despite the name, this class isn't really bound to the .NET ExportFactory<T>. The constructor simply takes a value, and an Action to invoke when the lifetime of that value is disposed.
For now, it is only available in Silverlight though. For the regular .NET framework you'll have to wait until .NET 4.x (or whatever the next version after 4.0 will be).
I don't think referencing the Autofac assembly is the real problem - I consider things like Owned appearing in application code a 'code smell'. Application code shouldn't care about what DI framework is being used and having Owned in your code now creates a hard dependency on Autofac. All DI related code should be cleanly contained in a set of configuration classes (Modules in the Autofac world).