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.
Related
We use ninject as our DI solution. How do I create a self sustaining class library dll with its own internal IOC. Basically I have created a service that does something and I want to register the bindings in the dll and just hand it to other people. I don't want them to care about any binding in my dll.
In the dll:
public class FirstService : IFirstService
{
public FirstService(ISecondService secondService, IThirdService thirdService)
{
//Saves locally
}
//Does stuff with second and third services
}
What the end user does:
public class ThirdService : IThirdService
{
//Create the actual implementation of this
}
What I want inside the dll:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IFirstService>.To<FirstService>();
kernel.Bind<ISecondService>.To<SecondService>();
}
I don't think I want to use IKernel here though, due to possible memory leakage.
There are 4 basic design approaches to DLLs that are commonly in use:
An application layer.
A plug-in.
A library.
A framework.
It sounds like you have one of the last 2, but it is not possible to tell based on your question which prototype you are referring to.
For an application layer, you would typically compose the components inside of the application, in the composition root, as close to the point of entry of the main executable application as possible.
For a plugin, it would typically have its own internal composition root that is fired by some method or event of the application it is plugging into (based on that application's composition root). This is sometimes facilitated by modules in DI containers.
A library would typically not have any internal composition, but would provide an API (sometimes implemented as a fluent builder) that makes it easy for the client application to compose the pieces together. See this post for a couple of ideas about how to do that.
A framework would need to have 1 or more explicit extension points for the application to integrate into. Think of how MVC controllers work. There is an internal scanning implementation that by default can instantiate any object that implements a certain interface. There is also an abstract factory that can be used to inject dependencies if the default constructor is not available (in MVC, that is IControllerFactory). See this post for more information about how to make a DI friendly framework.
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.
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.
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()
);
}
Say I have the following 4 .net assemblies:
Winforms UI
Business Logic
SQL Server Data Access (implementing an IRepository)
Common Interfaces (definition of IRepository etc.)
My business logic (2) makes calls to the data access layer (3) through IRepository (defined in 4) using constructor dependency injection. However when I ceate a business object I need to pass in an actual repository. I do this by having a singleton class in my business logic layer return the currently in use concrete object implementing IRepository. I am coming to the conclusion that this is a bad thing, as my business logic layer now has to reference 3 as well as 4.
I think I need a IoC Container but the question is where I create/put it as it seems that wherever I create this (1 - UI)? will also need to hold a reference to 3 (SQL Server Data Access). Am I not just moving the problem rather than achieving actual decoupling?
Do I create the IoC Container in the UI. Or expose it through another new assembly.
(I'm using C#, .net 3.5 and AutoFac)
Thanks.
IoC container generally should be created in the host project (application entry point). For the Windows.Forms application that's the exe project.
Generally in simple solutions (under 10 projects), only a host project should have a reference to IoC library.
PS: Structuring .NET Applications with Autofac IoC
When registering components there are several possibilities:
Registration in code:
directly
Problem: you have to reference everything ( you are here)
indirectly
Problem : to find out what has to be registered
Solution:
use attributes
use marker interface as IService
use conventions (see StructureMap)
Registration with configuration file:
let the container do everything
read the file yourself
Top level is a way to go (UI, as Rinat said).
Now as for references, simplest way is just to go over all assemblies in the current folder and use some convention to get the services out. Attributes work fine, putting registrar classes in each assembly works fine, whatever suits you. The code for extracting everything should probably be in a separate assembly, unless your IoC framework already does that.
The module distinction and the "scopes" defined by the modules exist mostly at compile-time. In the run-time it's all one big mess ;) This is used by most IOC containers and they don't really care about where they are located. The IoC container for a web-app will typically be created at the outermost level (very close to the web-container itself).
It's true that you could create it anywhere, but I'd introduce an extra layer, let's call it 3.5.
Your current 3 would be where your IoC resides for Data Access - this would become a wrapper for your actual DAL. Based on your config, 3 would create either a mock repository or a concrete one.
So 2 still references 3, but it's just an interface to the actual DAL which is configured through your IoC framework.
Alternatively, you could roll your own 'el-cheapo' IoC - change your Big Ugly Singleton to a Static Gateway - Abstracting IoC Container Behind a Singleton - Doing it wrong?