I have been trying to use Ninject today and have a couple of questions. First of all do I need to use the Inject attribute on all constructors that I want to use injection for. This seems like a really lame design? Do I need to create a Kernel then use that everywhere I pass in an injected class?
The best way to get started with Ninject is to start small. Look for a new.
Somewhere in the middle of your application, you're creating a class inside another class. That means you're creating a dependency. Dependency Injection is about passing in those dependencies, usually through the constructor, instead of embedding them.
Say you have a class like this, used to automatically create a specific type of note in Word. (This is similar to a project I've done at work recently.)
class NoteCreator
{
public NoteHost Create()
{
var docCreator = new WordDocumentCreator();
docCreator.CreateNewDocument();
[etc.]
WordDocumentCreator is a class that handles the specifics of creating a new document in Microsoft Word (create an instance of Word, etc.). My class, NoteCreator, depends on WordDocumentCreator to perform its work.
The trouble is, if someday we decide to move to a superior word processor, I have to go find all the places where WordDocumentCreator is instantiated and change them to instantiate WordPerfectDocumentCreator instead.
Now imagine that I change my class to look like this:
class NoteCreator
{
WordDocumentCreator docCreator;
public NoteCreator(WordDocumentCreator docCreator) // constructor injection
{
this.docCreator = docCreator;
}
public NoteHost Create()
{
docCreator.CreateNewDocument();
[etc.]
My code hasn't changed that much; all I've done within the Create method is remove the line with the new. But now I'm injecting my dependency. Let's make one more small change:
class NoteCreator
{
IDocumentCreator docCreator;
public NoteCreator(IDocumentCreator docCreator) // change to interface
{
this.docCreator = docCreator;
}
public NoteHost Create()
{
docCreator.CreateNewDocument();
[etc.]
Instead of passing in a concrete WordDocumentCreator, I've extracted an IDocumentCreator interface with a CreateNewDocument method. Now I can pass in any class that implements that interface, and all NoteCreator has to do is call the method it knows about.
Now the tricky part. I should now have a compile error in my app, because somewhere I was creating NoteCreator with a parameterless constructor that no longer exists. Now I need to pull out that dependency as well. In other words, I go through the same process as above, but now I'm applying it to the class that creates a new NoteCreator. When you start extracting dependencies, you'll find that they tend to "bubble up" to the root of your application, which is the only place where you should have a reference to your DI container (e.g. Ninject).
The other thing I need to do is configure Ninject. The essential piece is a class that looks like this:
class MyAppModule : NinjectModule
{
public override void Load()
{
Bind<IDocumentCreator>()
.To<WordDocumentCreator>();
This tells Ninject that when I attempt to create a class that, somewhere down the line, requires an IDocumentCreator, it should create a WordDocumentCreator and use that. The process Ninject goes through looks something like this:
Create the application's MainWindow. Its constructor requires a NoteCreator.
OK, so create a NoteCreator. But its constructor requires an IDocumentCreator.
My configuration says that for an IDocumentCreator, I should use WordDocumentCreator. So create a WordDocumentCreator.
Now I can pass the WordDocumentCreator to the NoteCreator.
And now I can pass that NoteCreator to the MainWindow.
The beauty of this system is threefold.
First, if you fail to configure something, you'll know right away, because your objects are created as soon as your application is run. Ninject will give you a helpful error message saying that your IDocumentCreator (for instance) can't be resolved.
Second, if management later mandates the user of a superior word processor, all you have to do is
Write a WordPerfectDocumentCreator that implements IDocumentCreator.
Change MyAppModule above, binding IDocumentCreator to WordPerfectDocumentCreator instead.
Third, if I want to test my NoteCreator, I don't have to pass in a real WordDocumentCreator (or whatever I'm using). I can pass in a fake one. That way I can write a test that assumes my IDocumentCreator works correctly, and only tests the moving parts in NoteCreator itself. My fake IDocumentCreator will do nothing but return the correct response, and my test will make sure that NoteCreator does the right thing.
For more information about how to structure your applications this way, have a look at Mark Seemann's recent book, Dependency Injection in .NET. Unfortunately, it doesn't cover Ninject, but it does cover a number of other DI frameworks, and it talks about how to structure your application in the way I've described above.
Also have a look at Working Effectively With Legacy Code, by Michael Feathers. He talks about the testing side of the above: how to break out interfaces and pass in fakes for the purpose of isolating behavior and getting it under test.
First of all do I need to use the Inject attribute on all constructors
that I want to use injection for. This seems like a really lame
design?
No you shouldn't have to do this at all actually. Since you work with ASP.NET MVC you can just install the Ninject.MVC3 Nuget package. This will get you started with a NinjectMVC3 class in the App_Start folder. You can use the RegisterServices method to register your interfaces/classes with Ninject. All controllers that have dependencies to those interfaces will then be automatically resolved by Ninject, there is no need for the Inject attribute.
Do I need to create a Kernel then use that everywhere I pass in an
injected class?
No - what you are describing sounds more like the Service Locator pattern, not dependency injection - you will want to pass in your dependencies ideally in the constructor, instead of resolving them within particular classes using the kernel. There should be just one central composition root where the resolving is done, which is within the composition root in either the RegisterServices method mentioned above or a separate Ninject module instantiated there - the later approach will allow you a little more flexibility and modularity (no pun intended) in changing how you resolve your dependencies.
Here's a good beginner's tutorial on dependency injection with Ninject and MVC3.
Don't forget there are docs, including an intro I feel would be very appropriate given the sort of questions you are asking on the Ninject Wiki. You're just annoying yourself if you're trying to use Ninject without reading it end to end.
Stick the table of contents on your bookmark bar for a bit.
I can also highly recommend Mark Seemann's Dependency Injection in .Net as a companion book for DI based architecture (even though it doesnt directly cover Ninject).
Related
I've been tasked with taking over a partially developed sizeable and complex UWP application using MVVM via Template 10. The app needs to use an in-house developed webservices API and this needs to be used for practically every single function, starting with the initial login page.
So given I need to access a single instance of the API everywhere how do I go about doing that correctly? I've used MVVM a fair bit but never used Template10 and never had to share an instance of an object across an entire MVVM UWP app before.
So far I can think of three ways:
Declare and instantiate API instance in Appl.xaml.cs and use it globally
Create a public Globals class and have the instance as a public static property:
c#
public class Globals
{
private static OurAPI _ourAPI;
public static OurAPI API
{
get { return _ourAPI; }
set { _ourAPI = value; }
}
}
Instantiate the API in the login page and then pass it as a parameter between ViewModels, presumably using the Navigation service.
I'm thinking 1 or 2 are most likely not MVVM compliant and could cause unit testing issues so maybe 3 is the best option? Or is there another, more correct way to do this to adhere to Template10/MVVM concepts and also be able to unit test it?
EDIT: Sorry about the code not formatting, the edit box formats it Ok but when I save it it goes back to one long sentence :-(
The best solution consists of a singleton service and inversion of control (IoC) / Dependency injection . This is a pretty complex topic so I definitely encourage to read about it from several sources.
In summary, you first create an interface for your service, where you declare all the public members and methods. Then you create an implementation of the interface. Then you use a IoC container and register your service as a singleton (single-instance) and then integrate the IoC so that it creates instances of your view models. Then you can put the interface as a constructor parameter of your view model and the IoC container will make sure to provide the singleton instance you registered.
In your case, you are using Template 10 which can be integrated with different IoC containers as seen in the documentation. Check out AutoFac as an example of an IoC container. You can see some examples of registering and resolving a service in the documentation.
For a general solution, check this SO question which demonstrates using AutoFac in UWP.
You can also see some code examples in this SO question and this one specifically for Template 10.
This solution is better than using static and global instances because you never actually deal with any hardcoded reference and actually always work just against the interface. You put the interface as the parameter of your constructor and IoC will take care of providing the instance for you. In addition - you can anytime swap the interface implementation for a different class and you just have to update it in one single location - the IoC registration.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed last month.
The community reviewed whether to reopen this question last month and left it closed:
Original close reason(s) were not resolved
Improve this question
Recently I've read Mark Seemann's article about Service Locator anti-pattern.
Author points out two main reasons why ServiceLocator is an anti-pattern:
API usage issue (which I'm perfectly fine with)
When class employs a Service locator it is very hard to see its dependencies as, in most cases, class has only one PARAMETERLESS constructor.
In contrast with ServiceLocator, DI approach explicitly exposes dependencies via constructor's parameters so dependencies are easily seen in IntelliSense.
Maintenance issue (which puzzles me)
Consider the following expample
We have a class 'MyType' which employs a Service locator approach:
public class MyType
{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
}
}
Now we want to add another dependency to class 'MyType'
public class MyType
{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
// new dependency
var dep2 = Locator.Resolve<IDep2>();
dep2.DoSomething();
}
}
And here is where my misunderstanding starts. The author says:
It becomes a lot harder to tell whether you are introducing a breaking change or not. You need to understand the entire application in which the Service Locator is being used, and the compiler is not going to help you.
But wait a second, if we were using DI approach, we would introduce a dependency with another parameter in constructor (in case of constructor injection). And the problem will be still there. If we may forget to setup ServiceLocator, then we may forget to add a new mapping in our IoC container and DI approach would have the same run-time problem.
Also, author mentioned about unit test difficulties. But, won't we have issues with DI approach? Won't we need to update all tests which were instantiating that class? We will update them to pass a new mocked dependency just to make our test compilable. And I don't see any benefits from that update and time spending.
I'm not trying to defend Service Locator approach. But this misunderstanding makes me think that I'm losing something very important. Could somebody dispel my doubts?
UPDATE (SUMMARY):
The answer for my question "Is Service Locator an anti-pattern" really depends upon the circumstances. And I definitely wouldn't suggest to cross it out from your tool list. It might become very handy when you start dealing with legacy code. If you're lucky enough to be at the very beginning of your project then the DI approach might be a better choice as it has some advantages over Service Locator.
And here are main differences which convinced me to not use Service Locator for my new projects:
Most obvious and important: Service Locator hides class dependencies
If you are utilizing some IoC container it will likely scan all constructor at startup to validate all dependencies and give you immediate feedback on missing mappings (or wrong configuration); this is not possible if you're using your IoC container as Service Locator
For details read excellent answers which are given below.
If you define patterns as anti-patterns just because there are some situations where it does not fit, then YES it's an anti pattern. But with that reasoning all patterns would also be anti patterns.
Instead we have to look if there are valid usages of the patterns, and for Service Locator there are several use cases. But let's start by looking at the examples that you have given.
public class MyType
{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
// new dependency
var dep2 = Locator.Resolve<IDep2>();
dep2.DoSomething();
}
}
The maintenance nightmare with that class is that the dependencies are hidden. If you create and use that class:
var myType = new MyType();
myType.MyMethod();
You do not understand that it has dependencies if they are hidden using service location. Now, if we instead use dependency injection:
public class MyType
{
public MyType(IDep1 dep1, IDep2 dep2)
{
}
public void MyMethod()
{
dep1.DoSomething();
// new dependency
dep2.DoSomething();
}
}
You can directly spot the dependencies and cannot use the classes before satisfying them.
In a typical line of business application you should avoid the use of service location for that very reason. It should be the pattern to use when there are no other options.
Is the pattern an anti-pattern?
No.
For instance, inversion of control containers would not work without service location. It's how they resolve the services internally.
But a much better example is ASP.NET MVC and WebApi. What do you think makes the dependency injection possible in the controllers? That's right -- service location.
Your questions
But wait a second, if we were using DI approach, we would introduce a
dependency with another parameter in constructor (in case of
constructor injection). And the problem will be still there.
There are two more serious problems:
With service location you are also adding another dependency: The service locator.
How do you tell which lifetime the dependencies should have, and how/when they should get cleaned up?
With constructor injection using a container you get that for free.
If we may
forget to setup ServiceLocator, then we may forget to add a new
mapping in our IoC container and DI approach would have the same
run-time problem.
That's true. But with constructor injection you do not have to scan the entire class to figure out which dependencies are missing.
And some better containers also validate all dependencies at startup (by scanning all constructors). So with those containers you get the runtime error directly, and not at some later temporal point.
Also, author mentioned about unit test difficulties. But, won't we have issues with DI approach?
No. As you do not have a dependency to a static service locator. Have you tried to get parallel tests working with static dependencies? It's not fun.
I would also like to point out that IF you are refactoring legacy code that the Service Locator pattern is not only not an anti-pattern, but it is also a practical necessity. No-one is ever going to wave a magic wand over millions of lines of code and suddenly all that code is going to be DI ready. So if you want to start introducing DI to an existing code base it is often the case that you will change things to become DI services slowly, and the code that references these services will often NOT be DI services. Hence THOSE services will need to use the Service Locator in order to get instances of those services that HAVE been converted to use DI.
So when refactoring large legacy applications to start to use DI concepts I would say that not only is Service Locator NOT an anti-pattern, but that it is the only way to gradually apply DI concepts to the code base.
From the testing point of view, Service Locator is bad. See Misko Hevery's Google Tech Talk nice explanation with code examples http://youtu.be/RlfLCWKxHJ0 starting at minute 8:45. I liked his analogy: if you need $25, ask directly for money rather than giving your wallet from where money will be taken. He also compares Service Locator with a haystack that has the needle you need and knows how to retrieve it. Classes using Service Locator are hard to reuse because of it.
Maintenance issue (which puzzles me)
There are 2 different reasons why using service locator is bad in this regard.
In your example, you are hard-coding a static reference to the service locator into your class. This tightly couples your class directly to the service locator, which in turns means it won't function without the service locator. Furthermore, your unit tests (and anybody else who uses the class) are also implicitly dependent on the service locator. One thing that has seemed to go unnoticed here is that when using constructor injection you don't need a DI container when unit testing, which simplifies your unit tests (and developers' ability to understand them) considerably. That is the realized unit testing benefit you get from using constructor injection.
As for why constructor Intellisense is important, people here seem to have missed the point entirely. A class is written once, but it may be used in several applications (that is, several DI configurations). Over time, it pays dividends if you can look at the constructor definition to understand a class's dependencies, rather than looking at the (hopefully up-to-date) documentation or, failing that, going back to the original source code (which might not be handy) to determine what a class's dependencies are. The class with the service locator is generally easier to write, but you more than pay the cost of this convenience in ongoing maintenance of the project.
Plain and simple: A class with a service locator in it is more difficult to reuse than one that accepts its dependencies through its constructor.
Consider the case where you need to use a service from LibraryA that its author decided would use ServiceLocatorA and a service from LibraryB whose author decided would use ServiceLocatorB. We have no choice other than using 2 different service locators in our project. How many dependencies need to be configured is a guessing game if we don't have good documentation, source code, or the author on speed dial. Failing these options, we might need to use a decompiler just to figure out what the dependencies are. We may need to configure 2 entirely different service locator APIs, and depending on the design, it may not be possible to simply wrap your existing DI container. It may not be possible at all to share one instance of a dependency between the two libraries. The complexity of the project could even be further compounded if the service locators don't happen to actually reside in the same libraries as the services we need - we are implicitly dragging additional library references into our project.
Now consider the same two services made with constructor injection. Add a reference to LibraryA. Add a reference to LibraryB. Provide the dependencies in your DI configuration (by analyzing what is needed via Intellisense). Done.
Mark Seemann has a StackOverflow answer that clearly illustrates this benefit in graphical form, which not only applies when using a service locator from another library, but also when using foreign defaults in services.
My knowledge is not good enough to judge this, but in general, I think if something has a use in a particular situation, it does not necessarily mean it cannot be an anti-pattern. Especially, when you are dealing with 3rd party libraries, you don't have full control on all aspects and you may end up using the not very best solution.
Here is a paragraph from Adaptive Code Via C#:
"Unfortunately, the service locator is sometimes an unavoidable anti-pattern. In some application types— particularly Windows Workflow Foundation— the infrastructure does not lend itself to constructor injection. In these cases, the only alternative is to use a service locator. This is better than not injecting dependencies at all. For all my vitriol against the (anti-) pattern, it is infinitely better than manually constructing dependencies. After all, it still enables those all-important extension points provided by interfaces that allow decorators, adapters, and similar benefits."
-- Hall, Gary McLean. Adaptive Code via C#: Agile coding with design patterns and SOLID principles (Developer Reference) (p. 309). Pearson Education.
I can suggest considering generic approach to avoid the demerits of Service Locator pattern.
It allows explicitly declaring class dependencies and substitute mocks and doesn't depend on a particular DI Container.
Possible drawbacks of this approach is:
It makes your control classes generic.
It is not easy to override some particular interface.
1 First Declare interface
public interface IResolver<T>
{
T Resolve();
}
Create ‘flattened’ class with implementing of resolving the most of frequently used interfaces from DI Container and register it.
This short example uses Service Locator but before composition root. Alternative way is inject each interface with constructor.
public class FlattenedServices :
IResolver<I1>,
IResolver<I2>,
IResolver<I3>
{
private readonly DIContainer diContainer;
public FlattenedServices(DIContainer diContainer)
{
this.diContainer = diContainer;
}
I1 IResolver<I1>.Resolve()
=> diContainer.Resolve<I1>();
I2 IResolver<I2>.Resolve()
=> diContainer.Resolve<I2>();
I3 IResolver<I3>.Resolve()
=> diContainer.Resolve<I3>();
}
Constructor injection on some MyType class should look like
public class MyType<T> : IResolver<T>
where T : class, IResolver<I1>, IResolver<I3>
{
T servicesContext;
public MyType(T servicesContext)
{
this.servicesContext = servicesContext
?? throw new ArgumentNullException(nameof(serviceContext));
_ = (servicesContext as IResolver<I1>).Resolve() ?? throw new ArgumentNullException(nameof(I1));
_ = (servicesContext as IResolver<I3>).Resolve() ?? throw new ArgumentNullException(nameof(I3));
}
public void MyMethod()
{
var dep1 = ((IResolver<I1>)servicesContext).Resolve();
dep1.DoSomething();
var dep3 = ((IResolver<I3>)servicesContext).Resolve();
dep3.DoSomething();
}
T IResolver<T>.Resolve() => serviceContext;
}
P.S. If you don't need to pass servicesContext further in MyType, you can declare object servicesContext; and make generic only ctor not class.
P.P.S. That FlattenedServices class could be considered as main DI container and a branded container could be considered as supplementary container.
The Author reasons that "the compiler won't help you" - and it is true.
When you deign a class, you will want to carefully choose its interface - among other goals to make it as independent as ... as it makes sense.
By having the client accept the reference to a service (to a dependency) through explicit interface, you
implicitly get checking, so the compiler "helps".
You're also removing the need for the client to know something about the "Locator" or similar mechanisms, so the client is actually more independent.
You're right that DI has its issues / disadvantages, but the mentioned advantages outweigh them by far ... IMO.
You're right, that with DI there is a dependency introduced in the interface (constructor) - but this is hopefully the very dependency that you need and that you want to make visible and checkable.
Yes, service locator is an anti-pattern it violates encapsulation and solid.
Service Locator(SL)
Service Locator solves [DIP + DI] issue. It allows by interface name satisfy needs. Service Locator can be as singleton or can be passed into constructor.
class A {
IB ib
init() {
ib = ServiceLocator.resolve<IB>();
}
}
The problem here that it is not clear which exactly classes(realizations of IB) are used by client(A).
proposal - pass parameter explicitly
class A {
IB ib
init(ib: IB) {
self.ib = ib
}
}
SL vs DI IoC Container(framework)
SL is about saving instances when DI IoC Container(framework) is more about creating instances.
SL works as a PULL command when it retrieves dependencies inside constructor
DI IoC Container(framework) works as a PUSH command when it put dependencies into constructor
I think that the author of the article shot himself on the foot in proving that it's an anti pattern with the update written 5 years later. There, it is said that this is the correct way:
public OrderProcessor(IOrderValidator validator, IOrderShipper shipper)
{
if (validator == null)
throw new ArgumentNullException("validator");
if (shipper == null)
throw new ArgumentNullException("shipper");
this.validator = validator;
this.shipper = shipper;
}
Then below is said:
Now it's clear that all three object are required before you can call the Process method; this version of the OrderProcessor class advertises its preconditions via the type system. You can't even compile client code unless you pass arguments to constructor and method (you can pass null, but that's another discussion).
Let me stress the last part again:
you can pass null, but that's another discussion
Why that is another discussion? That is a huge deal. An object that receives its dependencies as arguments fully depends on the previous execution of the application (or tests) to provide those objects as valid references/pointers. It is not "encapsulated" in the terms that the author expressed, as it depends on a lot of external machinery to run in a satisfactory manner for the object to be constructed at all, and later to work properly when it needs to use the other class.
The author claims that it's the Service Locator which is not encapsulated because it's depending on an additional object that you can't isolate from on the tests. But that other object could very well be a trivial map or vector, so it's pure data with no behavior. In C++, for example, containers are not part of the language, so you rely on containers (vectors, hash maps, strings, etc.) for all non-trivial classes. Are they not isolated because rely on containers? I don't think so.
I think that both using manual dependency injection or a service locator the objects are not really isolated from the rest: they need their dependencies, yes or yes, but are provided in a different way. I for one think that a locator even helps with the DRY principle, as it's error prone and repetitive to pass over and over pointers through the application. The service locator can also be more flexible in that an object might retrieve its dependencies when needed (if needed), not only via the constructor.
The problem of the dependencies not being explicit enough via the constructor of the object (on an object using the service locator) is solved by the very thing I stressed out before: passing null pointers. It can be even used to mix and match both systems: if the pointer is null, use the service locator, otherwise, use the pointer. Now it is enforced via the type system, and it's obvious to the user of the class. But we can do even better.
One additional solution that is surely doable with C++ (I don't know about Java/C#, but I suppose it could be done as well), is to write a helper class to be instantiated like LocatorChecker<IOrderValidator, IOrderShipper>. That object could check on it's constructor/destructor that the service locator holds a valid instance of the required classes, hence, being also less repetitive than the example provided by Mark Seeman.
Background
I'm using Castle Windsor as my IOC container in a WPF application. In this application, the user can open a single project file, which is modeled using a concrete version of an IProjectModel interface. So, at any given time there is zero or one instance(s) of IProjectModel available. I'm currently defining the lifestyle of its implementor as transient, and this implementor expects in its constructor a filename as a string which is chosen by the user (from a dialog). The IProjectModel instance is resolved via a typed factory interface, e.g.:
public interface IProjectModelFactory
{
IProjectModel Create(string fileName);
}
Question
I initially figured it was bad to treat it as a singleton since:
it is transient with respect to the application lifetime;
it has dependencies of its own, i.e. the filename (string) to open, that I don't think I could specify if it had singleton/scoped lifestyle;
passing it around keeps open the option of having multiple projects open at once.
However, now that I'm creating factory after factory in order to pass the current IProjectModel instance around I'm somewhat regretting that decision. It'd be much easier to have the container hand my objects the current project model, rather than pass it down from way up the object chain.
How is a situation like this supposed to be handled using Castle Windsor?
It seems like the Scoped Lifestyle is built for this (the scope is the currently open project/file name), but I can't figure out how to get information about the opened file into the IScopeAccessor since I can't inject anything into that.
IProjectModel sounds like it contains data--i.e. it's not a pure service.
Consider modeling it like you would model a service that was backed by a database, but instead of connecting to a database, use some in-memory construct. It's probably as simple as a static member variable on your service implementation. Something like:
public class ProjectDataService : IProjectDataService
{
private static IProjectModel _projectModel;
public IProjectModel Create(string fileName)
{
if (_projectModel == null)
{
//create it
}
return _projectModel;
}
}
(Note that you you may have to do some locking of the member variable.)
Now if you need to switch to having multiple projects open at once, change your member variable to a list structure (IList, Dictionary, etc.).
Edit based on your comment.
I'm referring to once it's already been created. The big idea behind IOC seems to be "let the container handle the dependencies", and it seems Windsor could support this, I just don't see how. I'd like to specify IProjectModel in a transient object's constructor, and have the container resolve the current IProjectModel, if there is one. Your answer is a lazy singleton, which isn't what I was asking for.
What I'm saying is IProjectModel is not really a service--it's state/data. So injecting it directly doesn't make sense (at least not to me). Wrapping it in a IProjectModel data service or IProjectModel "state manager" is more in line with injecting services, which is what DI frameworks generally do.
Can you register an IProjectModel? Yes. However, container registration is generally done at application bootstrap time, not based on user input. Also, from your description, you may need to support multiple instances of IProjectModel. How would the container know which instance to give to you when you ask for it?
As a more obvious example: would you consider injecting a string or an int in your constructor?
Let the container handle the dependencies is not exactly how I would describe the "big idea" behind IOC. It's about decoupling from (or handling) service dependencies. So if you want to inject something that is stateful, I'm suggesting you wrap that state in a class that can be injected like a service.
First of all, I've already scoured the web and SO for a solution, couldn't find anything.
I'm working on a highly decoupled solution, with all classes designed for a DI approach (asking interfaces as dependencies of course). We use Automapper in the MVC layer to transform server side POCOs in the flattened ViewModels. So far nothing strange.
The complexity is given by the fact that some properties of the ViewModels must be created using some services that are registered in the IoC container (ninject) and are not available during application start, where automapper is configured. Telling automapper what method to use to resolve types was easy, just one line of configuration as per documentation.
For simple cases, where a single property needs this behaviour, we create a custom ValueResolver for that property, expose the dependencies in the constructor and use them to return the desired value.
The problem arises when we have, let's say, 20 properties which need the same behaviour, but different output values, while all other ViewModel properties are fine with the default "automapping".
I can't find a way to tell automapper "to resolve those properties, use this class, for all the others just use your convention".
I tried several approaches, including putting the desired properties on an interface and then use Inheritance mapping as described on the wiki. It works as long as I don't use a TypeConverter, which is pointless, because I need it (or something like it) to get the services needed through DI/IoC.
An example:
public interface IMyInterface
{
string MyUrl1 {get;set;}
//snip with many other urls
}
public class MyViewModel : IMyInterface
{
public string MyUrl1 {get;set;}
//snip with many other urls
public string MyAutomapperProperty1 {get;set;}
//snip with many other properties where I want to use the conventions
}
What I need is something like this
public class MyTypeConverter : TypeConverter<MyPoco, IMyInterface>
{
// here in the overridden method return an instance of MyViewModel
// with just the properties exposed by the interface
}
Then in automapper config:
Automapper.CreateMap<MyPoco, IMyInterface>()
.Include<MyPoco, MyViewModel>()
.ConvertUsing<MyTypeConverter>();
Automapper.CreateMap<MyPoco, MyViewModel>();
This doesn't work. If I remove the call to ConvertUsing and add inline mappings with the ForMember method everything works, and the ForMember declarations are correctly inherited by the second mapping, but just not the ConvertUsing. But I can't have DI with the ForMember method (as I am in the application start, which is static, plus that would mean to instantiate those object at application level and keep them alive for all the application, instead of creating and disposing them when needed).
I know a solution is putting the related properties in a separate object and create a TypeConverter straight for that object and use it, but refactoring of those POCOs is not an option right now, and besides, it seems strange there isn't a way to make inheritance and DI work together.
Hoping that someone can help me out, thanks for reading.
UPDATE
As requested, I'll try to be more clear as what I want to achieve.
We have some "services", known at application level only through their interfaces. Something like:
public interface IUrlResolver { }
Which exposes a bunch of methods to get URLs related to our application, based on some parameters that we pass, and other stuff. The implementation might as well expose a dependency to other services (interfaces) and so on. Thus we use DI and let the IoC container resolver the chain of dependencies.
Now let's say my ViewModel has 50 properties, of which 30 are fine to go with the convention based mapping of automapper, while the other 20 need all to be resolved by different methods of my IUrlResolver interface. To get the facts straight:
I can't have DI where I configure automapper because it happens in Application_Start (or some static method called by application start)
I wouldn't have my IUrlResolver resolved at application level even if it was possible, because it would be stale for all application life
If I use a ValueResolver for a single property, everything is fine. The ValueResolver constructor requests IUrlResolver which gets injected at runtime when automapper transformation occurs.
I could create 20 different ValueResolver classes for my 20 properties, but it clutters the code, gets a ton of code duplication, no reusability, etc. A mess of bad practices.
What I want is the ability to partially map an object with a custom class (like a TypeConverter) while having all the other properties being mapped with the default convention engine
I don't have a "sample syntax" to post because the closest way I tried is the one I posted before. I'm open to a complete different approach if it exists, providing it allows me to keep things decoupled and doesn't involve refactoring those properties in a separate class.
I can't have DI where I configure automapper because it happens in
Application_Start (or some static method called by application start)
That sounds like a rather artificial constraint. Both DI container wire-up and AutoMapper configuration are presumably happening early in the application launch phase. It should be at least theoretically feasible to run your AutoMapper configuration after your DI container is configured. If there are practical reasons why this is not the case, could you please elaborate?
Addendum:
If the core problem is that you want to enable resolution of dependencies from your IoC container at mapping time, AutoMapper does provide hooks for this. See https://github.com/AutoMapper/AutoMapper/wiki/Custom-value-resolvers#custom-constructor-methods and https://github.com/AutoMapper/AutoMapper/wiki/Containers for two candidate approaches that you could use.
Currently I'm trying to understand dependency injection better and I'm using asp.net MVC to work with it. You might see some other related questions from me ;)
Alright, I'll start with an example controller (of an example Contacts Manager asp.net MVC application)
public class ContactsController{
ContactsManagerDb _db;
public ContactsController(){
_db = ContactsManagerDb();
}
//...Actions here
}
Allright, awesome that's working. My actions can all use the database for CRUD actions. Now I've decided I wanted to add unit testing, and I've added another contructor to mock a database
public class ContactsController{
IContactsManagerDb _db;
public ContactsController(){
_db = ContactsManagerDb();
}
public ContactsController(IContactsManagerDb db){
_db = db;
}
//...Actions here
}
Awesome, that's working to, in my unit tests I can create my own implementation of the IContactsManagerDb and unit test my controller.
Now, people usually make the following decision (and here is my actual question), get rid of the empty controller, and use dependency injection to define what implementation to use.
So using StructureMap I've added the following injection rule:
x.For<IContactsManagerDb>().Use<ContactsManagerDb>();
And ofcourse in my Testing Project I'm using a different IContactsManagerDb implementation.
x.For<IContactsManagerDb>().Use<MyTestingContactsManagerDb>();
But my question is, **What problem have I solved or what have I simplified by using dependency injection in this specific case"
I fail to see any practical use of it now, I understand the HOW but not the WHY? What's the use of this? Can anyone add to this project perhaps, make an example how this is more practical and useful?
The first example is not unit testable, so it is not good as it is creating a strong coupling between the different layers of your application and makes them less reusable. The second example is called poor man dependency injection. It's also discussed here.
What is wrong with poor man dependency injection is that the code is not autodocumenting. It doesn't state its intent to the consumer. A consumer sees this code and he could easily call the default constructor without passing any argument, whereas if there was no default constructor it would have immediately been clear that this class absolutely requires some contract to be passed to its constructor in order to function normally. And it is really not to the class to decide which specific implementation to choose. It is up to the consumer of this class.
Dependency injection is useful for 3 main reasons :
It is a method of decoupling interfaces and implementations.
It is good for reducing the amount of boiler plate / factory methods in an application.
It increases the modularity of packages.
As an example - consider the Unit test which required access to a class, defined as an interface. In many cases, a unit test for an interface would have to invoke implementations of that interface -- thus if an implementation changed, so would the unit test. However, with DI, you could "inject" an interface's implementation at run time into a unit test using the injection API - so that changes to implementations only have to be handled by the injection framework, not by individual classes that use those implementations.
Another example is in the web world : Consider the coupling between service providers and service definitions. If a particular component needs access to a service - it is better to design to the interface than to a particular implementation of that service. Injection enables such design, again, by allowing you to dynamically add dependencies by referencing your injection framework.
Thus, the various couplings of classes to one another are moved out of factories and individual classes, and dealt with in a uniform, abstract, reusable, and easily-maintained manner when one has a good DI framework. The best tutorials on DI that I have seen are on Google's Guice tutorials, available on YouTube. Although these are not the same as your particular technology, the principles are identical.
First, your example won't compile. var _db; is not a valid statement because the type of the variable has to be inferred at declaration.
You could do var _db = new ContactsManagerDb();, but then your second constructor won't compile because you're trying to assign an IContactsManagerDb to an instance of ContactsManagerDb.
You could change it to IContactsManagerDb _db;, and then make sure that ContactsManagerDb derives from IContactsManagerDb, but then that makes your first constructor irrelvant. You have to have the constructor that takes the interface argument anyways, so why not just use it all the time?
Dependency Injection is all about removing dependancies from the classes themselves. ContactsController doesn't need to know about ContactsManagerDb in order to use IContactsManagerDb to access the Contacts Manager.