I have been looking at various dependency injection frameworks for .NET as I feel the project I am working on would greatly benefit from it. While I think I have a good grasp of the capabilities of these frameworks, I am still a little unclear on how best to introduce them into a large system. Most demos (understandably) tend to be of quite simple classes that have one or two dependencies.
I have three questions...
First, how do you deal with those common but uninteresting dependencies, e.g. ILog, IApplicationSettings, IPermissions, IAudit. It seems overkill for every class to have these as parameters in their constructor. Would it be better to use a static instance of the DI container to get these when they are needed?
MyClass(ILog log, IAudit audit, IPermissions permissions, IApplicationSettings settings)
// ... versus ...
ILog log = DIContainer.Get<ILog>();
Second, how do you approach dependencies that might be used, but may be expensive to create. Example - a class might have a dependency on an ICDBurner interface but not want the concrete implementation to be created unless the CD Burning feature was actually used. Do you pass in interfaces to factories (e.g. ICDBurnerFactory) in the constructor, or do you again go with some static way of getting directly to the DI Container and ask for it at the point it is needed?
Third, suppose you have a large Windows Forms application, in which the top level GUI component (e.g. MainForm) is the parent of potentially hundreds of sub-panels or modal forms, each of which may have several dependencies. Does this mean that MainForm should be set up to have as dependencies the superset of all the dependencies of its children? And if you did so, wouldn't this end up creating a huge self-inflating monster that constructs every single class it could ever need the moment you create MainForm, wasting time and memory in the process?
Well, while you can do this as described in other answers I believe there is more important thing to be answered regarding your example and that is that you are probably violating SRP principle with class having many dependencies.
What I would consider in your example is breaking up the class in couple of more coherent classes with focused concerns and thus the number of their dependencies would fall down.
Nikola's law of SRP and DI
"Any class having more than 3
dependencies should be questioned for
SRP violation"
(To avoid lengthy answer, I posted in detail my answers on IoC and SRP blog post)
First: Add the simple dependencies to your constructor as needed. There is no need to add every type to every constructor, just add the ones you need. Need another one, just expand the constructor. Performance should not be a big thing as most of these types are likely to be singletons so already created after the first call. Do not use a static DI Container to create other objects. Instead add the DI Container to itself so it can resolve itself as a dependency. So something like this (assuming Unity for the moment)
IUnityContainer container = new UnityContainer();
container.RegisterInstance<IUnityContainer>(container);
This way you can just add a dependency on IUnityContainer and use that to create expensive or seldom needed objects. The main advantage is that it is much easier when unit testing as there are no static dependencies.
Second: No need to pass in a factory class. Using the technique above you can use the DI container itself to create expensive objects when needed.
Three: Add the DI container and the light singleton dependencies to the main form and create the rest through the DI container as needed. Takes a little more code but as you said the startup cost and memory consumption of the mainform would go through the roof if you create everything at startup time.
First:
You could inject these objects, when needed, as members instead of in the constructor. That way you don't have to make changes to the constructor as your usage changes, and you also don't need to use a static.
Second:
Pass in some sort of builder or factory.
Third:
Any class should only have those dependencies that it itself requires. Subclasses should be injected with their own specific dependencies.
I have a similar case related to the "expensive to create and might be used", where in my own IoC implementation, I'm adding automagic support for factory services.
Basically, instead of this:
public SomeService(ICDBurner burner)
{
}
you would do this:
public SomeService(IServiceFactory<ICDBurner> burnerFactory)
{
}
ICDBurner burner = burnerFactory.Create();
This has two advantages:
Behind the scenes, the service container that resolved your service is also used to resolve the burner, if and when it is requested
This alleviates the concerns I've seen before in this kind of case where the typical way would be to inject the service container itself as a parameter to your service, basically saying "This service requires other services, but I'm not going to easily tell you which ones"
The factory object is rather easy to make, and solves a lot of problems.
Here's my factory class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LVK.IoC.Interfaces;
using System.Diagnostics;
namespace LVK.IoC
{
/// <summary>
/// This class is used to implement <see cref="IServiceFactory{T}"/> for all
/// services automatically.
/// </summary>
[DebuggerDisplay("AutoServiceFactory (Type={typeof(T)}, Policy={Policy})")]
internal class AutoServiceFactory<T> : ServiceBase, IServiceFactory<T>
{
#region Private Fields
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly String _Policy;
#endregion
#region Construction & Destruction
/// <summary>
/// Initializes a new instance of the <see cref="AutoServiceFactory<T>"/> class.
/// </summary>
/// <param name="serviceContainer">The service container involved.</param>
/// <param name="policy">The policy to use when resolving the service.</param>
/// <exception cref="ArgumentNullException"><paramref name="serviceContainer"/> is <c>null</c>.</exception>
public AutoServiceFactory(IServiceContainer serviceContainer, String policy)
: base(serviceContainer)
{
_Policy = policy;
}
/// <summary>
/// Initializes a new instance of the <see cref="AutoServiceFactory<T>"/> class.
/// </summary>
/// <param name="serviceContainer">The service container involved.</param>
/// <exception cref="ArgumentNullException"><paramref name="serviceContainer"/> is <c>null</c>.</exception>
public AutoServiceFactory(IServiceContainer serviceContainer)
: this(serviceContainer, null)
{
// Do nothing here
}
#endregion
#region Public Properties
/// <summary>
/// Gets the policy that will be used when the service is resolved.
/// </summary>
public String Policy
{
get
{
return _Policy;
}
}
#endregion
#region IServiceFactory<T> Members
/// <summary>
/// Constructs a new service of the correct type and returns it.
/// </summary>
/// <returns>The created service.</returns>
public IService<T> Create()
{
return MyServiceContainer.Resolve<T>(_Policy);
}
#endregion
}
}
Basically, when I build the service container from my service container builder class, all service registrations are automatically given another co-service, implementing IServiceFactory for that service, unless the programmer has explicitly registered on him/her-self for that service. The above service is then used, with one parameter specifying the policy (which can be null if policies aren't used).
This allows me to do this:
var builder = new ServiceContainerBuilder();
builder.Register<ISomeService>()
.From.ConcreteType<SomeService>();
using (var container = builder.Build())
{
using (var factory = container.Resolve<IServiceFactory<ISomeService>>())
{
using (var service = factory.Instance.Create())
{
service.Instance.DoSomethingAwesomeHere();
}
}
}
Of course, a more typical use would be with your CD Burner object. In the above code I would resolve the service instead of course, but it's an illustration of what happens.
So with your cd burner service instead:
var builder = new ServiceContainerBuilder();
builder.Register<ICDBurner>()
.From.ConcreteType<CDBurner>();
builder.Register<ISomeService>()
.From.ConcreteType<SomeService>(); // constructor used in the top of answer
using (var container = builder.Build())
{
using (var service = container.Resolve<ISomeService>())
{
service.Instance.DoSomethingHere();
}
}
inside the service, you could now have a service, a factory service, which knows how to resolve your cd burner service upon request. This is useful for the following reasons:
You might want to resolve more than one service at the same time (burn two discs simultaneously?)
You might not need it, and it could be costly to create, so you only resolve it if needed
You might need to resolve, dispose, resolve, dispose, multiple times, instead of hoping/trying to clean up an existing service instance
You're also flagging in your constructor which services you need and which ones you might need
Here's two at the same time:
using (var service1 = container.Resolve<ISomeService>())
using (var service2 = container.Resolve<ISomeService>())
{
service1.Instance.DoSomethingHere();
service2.Instance.DoSomethingHere();
}
Here's two after each other, not reusing the same service:
using (var service = container.Resolve<ISomeService>())
{
service.Instance.DoSomethingHere();
}
using (var service = container.Resolve<ISomeService>())
{
service.Instance.DoSomethingElseHere();
}
First:
You might approach it by creating a container to hold your "uninteresting" dependencies (ILog, ICache, IApplicationSettings, etc), and use constructor injection to inject that, then internal to the constructor, hydrate the fields of the service from container.Resolve() ? I'm not sure I'd like that, but, well, it's a possibility.
Alternatively, you might like to use the new IServiceLocator common interface (http://blogs.msdn.com/gblock/archive/2008/10/02/iservicelocator-a-step-toward-ioc-container-service-locator-detente.aspx) instead of injecting the dependencies?
Second:
You could use setter injection for the optional/on-demand dependencies? I think I would go for injecting factories and new up from there on-demand.
To partially answer my first question, I've just found a blog post by Jeremy Miller, showing how Structure Map and setter injection can be used to auto-populate public properties of your objects. He uses ILogger as an example:
var container = new Container(r =>
{
r.FillAllPropertiesOfType<ILogger>().TheDefault.Is
.ConstructedBy(context => new Logger(context.ParentType));
});
This means that any classes with an ILogger property, e.g.:
public class ClassWithLogger
{
public ILogger Logger { get; set; }
}
public class ClassWithLogger2
{
public ILogger Logger { get; set; }
}
will have their Logger property automatically set up when constructed:
container.GetInstance<ClassWithLogger>();
Related
I'm struggling with a particular dependency injection problem and I just can't seem to figure it out. FYI: I'm new to guice, but I have experience with other DI frameworks - that's why I believe this shouldn't be to complicated to achieve.
What am I doing:
I'm working on Lagom multi module project and using Guice as DI.
What I would like to achieve:
Inject multiple named instances of some interface implementation (lets' call it publisher, since it will publishing messages to kafka topic) to my service.
This 'publisher' has injected some Lagom and Akka related services (ServiceLocator, ActorSystem, Materializer, etc..).
Now I would like to have two instances of such publisher and each will publish messages to different topic (So one publisher instance per topic).
How would I achieve that?
I have no problem with one instance or multiple instances for the same topic, but if I want to inject different topic name for each instance I have a problem.
So my publisher implementation constructor looks like that:
#Inject
public PublisherImpl(
#Named("topicName") String topic,
ServiceLocator serviceLocator,
ActorSystem actorSystem,
Materializer materializer,
ApplicationLifecycle applicationLifecycle) {
...
}
If I want to create one instance I would do it like this in my ServiceModule:
public class FeedListenerServiceModule extends AbstractModule implements ServiceGuiceSupport {
#Override
protected void configure() {
bindService(MyService.class, MyServiceImpl.class);
bindConstant().annotatedWith(Names.named("topicName")).to("topicOne");
bind(Publisher.class).annotatedWith(Names.named("publisherOne")).to(PublisherImpl.class);
}
}
How would I bind multiple publishers each for it's own topic?
I was playing around with implementing another private module:
public class PublisherModule extends PrivateModule {
private String publisherName;
private String topicName;
public PublisherModule(String publisherName, String topicName) {
this.publisherName = publisherName;
this.topicName = topicName;
}
#Override
protected void configure() {
bindConstant().annotatedWith(Names.named("topicName")).to(topicName);
bind(Publisher.class).annotatedWith(Names.named(publisherName)).to(PublisherImpl.class);
}
}
but this led me nowhere since you can't get injector in you module configuration method:
Injector injector = Guice.createInjector(this); // This will throw IllegalStateException : Re-entry is not allowed
injector.createChildInjector(
new PublisherModule("publisherOne", "topicOne"),
new PublisherModule("publisherTwo", "topicTwo"));
The only solution which is easy and it works is that I change my PublisherImpl to abstract, add him abstract 'getTopic()' method and add two more implementations with topic override.
But this solution is lame. Adding additional inheritance for code reuse is not exactly the best practice. Also I believe that Guice for sure must support such feature.
Any advises are welcome.
KR, Nejc
Don't create a new Injector within a configure method. Instead, install the new modules you create. No child injectors needed—as in the PrivateModule documentation, "Private modules are implemented using parent injectors", so there's a child injector involved anyway.
install(new PublisherModule("publisherOne", "topicOne"));
install(new PublisherModule("publisherTwo", "topicTwo"));
Your technique of using PrivateModule is the one I'd go with in this situation, particularly given the desire to make the bindings available through binding annotations as you have it, and particularly if the full set of topics is known at runtime. You could even put the call to install in a loop.
However, if you need an arbitrary number of implementations, you may want to create an injectable factory or provider to which you can pass a String set at runtime.
public class PublisherProvider {
// You can inject Provider<T> for all T bindings in Guice, automatically, which
// lets you configure in your Module whether or not instances are shared.
#Inject private final Provider<ServiceLocator> serviceLocatorProvider;
// ...
private final Map<String, Publisher> publisherMap = new HashMap<>();
public Publisher publisherFor(String topicName) {
if (publisherMap.containsKey(topicName)) {
return publisherMap.get(topicName);
} else {
PublisherImpl publisherImpl = new PublisherImpl(
topicName, serviceLocatorProvider.get(), actorSystemProvider.get(),
materializerProvider.get(), applicationLifecycleProvider.get());
publisherMap.put(topicName, publisherImpl);
return publisherImpl;
}
}
}
You'd probably want to make the above thread-safe; in addition, you can avoid the explicit constructor call by using assisted injection (FactoryModuleBuilder) or AutoFactory, which will automatically pass through explicit parameters like topicName while injecting DI providers like ServiceLocator (which hopefully has a specific purpose, because you may not need much service-locating within a DI framework anyway!).
(Side note: Don't forget to expose your annotated binding for your PrivateModule. If you don't find yourself injecting your topicName anywhere else, you might also consider using individual #Provides methods with the assisted injection or AutoFactory approach above, but if you expect each Publisher to need a differing object graph you might choose the PrivateModule approach anyway.)
Guice's approach to dependency injection is that the DI framework complements your instantiation logic, it doesn't replace it. Where it can, it will instantiate things for you, but it doesn't try to be too clever about it. It also doesn't confuse configuration (topic names) with dependency injection - it does one thing, DI, and does that one thing well. So you can't use it to configure things, the way you can with Spring for example.
So if you want to instantiate an object with two different parameters, then you instantiate that object with two different parameters - ie, you invoke new twice. This can be done by using provider methods, which are documented here:
https://github.com/google/guice/wiki/ProvidesMethods
In your case, it might look something like adding the following method to your module:
#Provides
#Named("publisherOne")
#Singleton
Publisher providePublisherOne(ServiceLocator serviceLocator,
ActorSystem actorSystem,
Materializer materializer,
ApplicationLifecycle applicationLifecycle) {
return new PublisherImpl("topicOne", serviceLocator,
actorSystem, materializer, applicationLifecycle);
}
Also, you probably want it to be a singleton if you're adding a lifecycle hook, otherwise you could run into memory leaks each time you add a new hook every time it's instantiated.
I'm just getting started with Unity, and I'm having trouble finding any advice about where to declare my UnityContainer object. Most of the examples that I've seen consist of just a single method where the UnityContainer object is declared at the top, then its mappings are defined, then a few object types are resolved. But how do you handle the container when you need to access it in several places throughout the program? For example, the user clicks on a button which opens a new window and that window needs a controller, which itself needs to resolve several services? I also want some of the services that Unity manages to be singletons, so wouldn't that mean that I'd have to have only a single instance of my UnityContainer throughout my program to manage those singletons?
My first thought is to have my main Program class have a static UnityContainer property or expose some sort of UnityContainerFactory class which manages a singleton UnityContainer instance, but both of those methods seem bad because they create a global property which a lot of things are dependent on.
What's the accepted way of doing this?
As noted in the other answer, you should compose the entire object graph in the Composition Root.
Don't declare the container as a static field since this would encourage developers to use it as a service locator which is an anti-pattern.
How to solve your problem?
Use Dependency Injection.
Here is an example for your special WinForms case:
In your Program.Main method, create the container, register the service (the dependency that you need to use from the other window) and then resolve the main form and run it like this:
UnityContainer container = new UnityContainer();
container.RegisterType<IService, Service>();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(container.Resolve<MainForm>());
In the MainForm, declare a dependency on a Func<SecondForm> where SecondForm is the form that you need to create from the main form when the button is clicked. Consider the following code inside your main form file:
public partial class MainForm : Form
{
private readonly Func<SecondForm> m_SecondFormFactory;
public MainForm(Func<SecondForm> second_form_factory)
{
m_SecondFormFactory = second_form_factory;
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
SecondForm second_form = m_SecondFormFactory();
second_form.Show();
}
}
Please note that Func<SecondForm> acts as some kind of factory. I use it in this case because unity has a feature to support late construction of dependencies via Func.
The SecondForm has a dependency on IService like this:
public partial class SecondForm : Form
{
private readonly IService m_Service;
public SecondForm(IService service)
{
m_Service = sevice;
InitializeComponent();
}
//Use service here
}
You can now use IService from the second form.
Using Seemann words:
As close as possible to the application's entry point.
Give a look at http://blog.ploeh.dk/2011/07/28/CompositionRoot/ from the great Seemann.
I think that is totally acceptable for the main container to be a static field that get disposed together with your application, just remember to don't tie your classes to your container.
Get noticed of the so called "Service Locator" (again from Seemann: http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/)
Where to declare it really depends on the application, I'd go for the startup class of an owin application or the Main method of a console/WPF app.
I am in the process of migrating from StructureMap to Simple Injector in a ASP.NET MVC3 application.
I am using the MVC3 extension for controller DI, but I am running into an issue with trying to replace the static aspects of StructureMap. We have calls to
StructureMap.ObjectFactory.GetInstance<Interface>()
throughout different layers of the app. It does not look like Simple Injector has a way to do that.
Am I missing something? Or is Simple Injector not applicable for my application?
Please advise and thanks in advance.
Allowing the application to directly access the container is considered to be bad practice. It is an form of the Service Locator anti-pattern.
Because this is considered to be a bad thing, Simple Injector does not contain anything like StructureMap's ObjectFactory.GetInstance. And as a matter of fact, the author of StructureMap is considering the removal of the ObjectFactory API in a furure release of StructureMap.
However, nothing stops you from storing the SimpleInjector.Container instance in a static field and let the application use this:
// Service Locator implementation in low application layer.
public static class ObjectFactory
{
private static SimpleInjector.Container container;
public static void SetContainer(Container container)
{
ObjectFactory.container = container;
}
public static T GetInstance<T>() where T : class
{
return container.GetInstance<T>();
}
}
In Composition root:
public static void Initialize()
{
var container = new Container();
InitializeContainer(container);
DependencyResolver.SetResolver(
new SimpleInjectorDependencyResolver(container));
// Set the service locator here
ObjectFactory.SetContainer(container);
}
So there is no limitation in the Simple Injector that prevents you from doing this, but frankly, you are already witnessing one of the reasons why Service Locator is a bad thing: you switched containers and now you have to change application code.
Perhaps for now it is easiest for you to save the container in a static field (as shown in the example above), but please take the time to understand why this pattern is bad, and do refactor away from this pattern towards dependency injection (and especially constructor injection).
I am used to IoC/DI in web applications - mainly Ninject with MVC3. My controller is created for me, filled in with all dependencies in place, subdependencies etc.
However, things are different in a thick client application. I have to create my own objects, or I have to revert to a service locator style approach where I ask the kernel (probably through some interface, to allow for testability) to give me an object complete with dependencies.
However, I have seen several places that Service Locator has been described as an anti-pattern.
So my question is - if I want to benefit from Ninject in my thick client app, is there a better/more proper way to get all this?
Testability
Proper DI / IoC
The least amount of coupling possible
Please note I am not just talking about MVVM here and getting view models into views. This is specifically triggered by a need to provide a repository type object from the kernel, and then have entities fetched from that repository injected with functionality (the data of course comes from the database, but they also need some objects as parameters depending on the state of the world, and Ninject knows how to provide that). Can I somehow do this without leaving both repositories and entities as untestable messes?
If anything is unclear, let me know. Thanks!
EDIT JULY 14th
I am sure that the two answers provided are probably correct. However, every fiber of my body is fighting this change; Some of it is probably caused by a lack of knowledge, but there is also one concrete reason why I have trouble seeing the elegance of this way of doing things;
I did not explain this well enough in the original question, but the thing is that I am writing a library that will be used by several (4-5 at first, maybe more later) WPF client applications. These applications all operate on the same domain model etc., so keeping it all in one library is the only way to stay DRY. However, there is also the chance that customers of this system will write their own clients - and I want them to have a simple, clean library to talk to. I don't want to force them to use DI in their Composition Root (using the term like Mark Seeman in his book) - because that HUGELY complicates things in comparison to them just newing up a MyCrazySystemAdapter() and using that.
Now, the MyCrazySystemAdapter (name chosen because I know people will disagree with me here) needs to be composed by subcomponents, and put together using DI. MyCrazySystemAdapter itself shouldn't need to be injected. It is the only interface the clients needs to use to talk to the system. So a client happily should get one of those, DI happens like magic behind the scenes, and the object is composed by many different objects using best practices and principles.
I do realize that this is going to be a controversial way of wanting to do things. However, I also know the people who are going to be clients of this API. If they see that they need to learn and wire up a DI system, and create their whole object structure ahead of time in their application entry point (Composition Root), instead of newing up a single object, they will give me the middle finger and go mess with the database directly and screw things up in ways you can hardly imagine.
TL;DR: Delivering a properly structured API is too much hassle for the client. My API needs to deliver a single object - constructed behind the scenes using DI and proper practices - that they can use. The real world some times trumps the desire to build everything backwards in order to stay true to patterns and practices.
I suggest to have a look at MVVM frameworks like Caliburn. They provide integration with IoC containers.
Basically, you should build up the complete application in your app.xaml. If some parts need to be created later because you do not yet know everything to create them at startup then inject a factory either as interface (see below) or Func (see Does Ninject support Func (auto generated factory)?) into the class that needs to create this instance. Both will be supported natively in the next Ninject release.
e.g.
public interface IFooFactory { IFoo CreateFoo(); }
public class FooFactory : IFooFactory
{
private IKernel kernel;
FooFactory(IKernel kernel)
{
this.kernel = kernel;
}
public IFoo CreateFoo()
{
this.kernel.Get<IFoo>();
}
}
Note that the factory implementation belongs logically to the container configuration and not to the implementation of your business classes.
I don't know anything about WPF or MVVM, but your question is basically about how to get stuff out of the container without using a Service Locator (or the container directly) all over the place, right?
If yes, I can show you an example.
The point is that you use a factory instead, which uses the container internally. This way, you are actually using the container in one place only.
Note: I will use an example with WinForms and not tied to a specific container (because, as I said, I don't know WPF...and I use Castle Windsor instead of NInject), but since your basic question is not specificaly tied to WPF/NInject, it should be easy for you to "port" my answer to WFP/NInject.
The factory looks like this:
public class Factory : IFactory
{
private readonly IContainer container;
public Factory(IContainer container)
{
this.container = container;
}
public T GetStuff<T>()
{
return (T)container.Resolve<T>();
}
}
The main form of your app gets this factory via constructor injection:
public partial class MainForm : Form
{
private readonly IFactory factory;
public MainForm(IFactory factory)
{
this.factory = factory;
InitializeComponent(); // or whatever needs to be done in a WPF form
}
}
The container is initialized when the app starts, and the main form is resolved (so it gets the factory via constructor injection).
static class Program
{
static void Main()
{
var container = new Container();
container.Register<MainForm>();
container.Register<IFactory, Factory>();
container.Register<IYourRepository, YourRepository>();
Application.Run(container.Resolve<MainForm>());
}
}
Now the main form can use the factory to get stuff like your repository out of the container:
var repo = this.factory.GetStuff<IYourRepository>();
repo.DoStuff();
If you have more forms and want to use the factory from there as well, you just need to inject the factory into these forms like into the main form, register the additional forms on startup as well and open them from the main form with the factory.
Is this what you wanted to know?
EDIT:
Ruben, of course you're right. My mistake.
The whole stuff in my answer was an old example that I had lying around somewhere, but I was in a hurry when I posted my answer and didn't read the context of my old example carefully enough.
My old example included having a main form, from which you can open any other form of the application. That's what the factory was for, so you don't have to inject every other form via constructor injection into the main form.
Instead, you can use the factory to open any new form:
var form = this.factory.GetStuff<IAnotherForm>();
form.Show();
Of course you don't need the factory just to get the repository from a form, as long as the repository is passed to the form via constructor injection.
If your app consists of only a few forms, you don't need the factory at all, you can just pass the forms via constructor injection as well:
public partial class MainForm : Form
{
private readonly IAnotherForm form;
// pass AnotherForm via constructor injection
public MainForm(IAnotherForm form)
{
this.form = form;
InitializeComponent(); // or whatever needs to be done in a WPF form
}
// open AnotherForm
private void Button1_Click(object sender, EventArgs e)
{
this.form.Show();
}
}
public partial class AnotherForm : Form
{
private readonly IRepository repo;
// pass the repository via constructor injection
public AnotherForm(IRepository repo)
{
this.repo= repo;
InitializeComponent(); // or whatever needs to be done in a WPF form
// use the repository
this.repo.DoStuff();
}
}
I'm trying to think of a good way to clean up my controllers to make them more testable without having to rely on a constant database connection. I thought I had a decent start by abstracting away my object context with an IObjectContext. This works well for the context, but my next problem is that I have a generic repository that I use in a number of action methods throughout my project (see code below).
In addition to the default constructor, my controller consists of an overload, which accepts an IObjectContext (simple dependency injection). In my unit tests, I can easily mock the IObjectContext. My issue is dealing with my generic repository in various action methods. I could add a number of additional constructor overloads to the controller, but I'm afraid this would get messy, really quickly. Short of doing that, however, I simply haven't been able to think of a clean way to improve testability so that I don't have to rely on a database connection.
Is there a simple solution that I'm overlooking?
/// <summary>
/// Initializes a new instance of the HomeController class
/// </summary>
public HomeController(IObjectContext context)
{
_context = context;
}
/// <summary>
/// GET: /home/index
/// </summary>
/// <returns>Renders the home page</returns>
public ActionResult Index()
{
List contacts;
HomeViewModel model;
using (IRepository<Contact> repository = new DataRepository<Contact>(_context))
{
contacts = new List(repository.GetAll());
}
model = new HomeViewModel(contacts);
return View(model);
}
If I have to go the route of adding additional constructor overloads to accommodate my concerns, I was considering adding a number of private properties (which would deffer instantiation of the repositories until they are needed) to my controllers for each of the repositories that action methods make use of. For example:
private IRepository<Contact> _contactRepository;
private IRepository<Contact> ContactRepository
{
get
{
return _contactRepository ?? (_contactRepository = new DataRepository<Contact>());
}
}
For unit testing purposes, I'd be able to pre-initialize the repositories using the constructor overloads.
What are your thoughts on this? Am I missing something cleaner that should be obvious?
First of all, get rid of your current Bastard Injection constructor overloads. With DI, you should only need one constructor, and that's the one that takes all the dependencies. (To enable the ASP.NET MVC run-time to create the Controllers, implement a custom IControllerFactory.)
The next step is to inject all your dependencies through the constructor. When you think it gets messy because there are too many constructor parameters, it's a good sign that you are violating the Single Responsibility Principle. When that happens, you extract an Aggregate Service.
Rinse and repeat :)
Well, I do what your final example shows all the time to inject mocks into my controllers. It does have a little smell to it (designing for testability), but it isn't bad coding and works great for testing.
Your use of a generic repository is more a dependency-cloaking device than a dependency injection. You should be able to see all of the dependencies a particular Controller uses: a generic repository hides this fact somewhere deep in the entrails of your Controllers which makes maintaining (and unit-testing) the code much more difficult. My suggestion: use concrete repositories.
You could also take a look at domain-driven design stuff.