My views extend a base view class ive made:
public class BaseView : ViewPage
At the moment im calling ObjectFactory.GetInstance inside this class' constructor to get some interface implementations but id like to use structuremap to inject them as constructor arguments.
Im using a structuremapcontrollerfactory to create my controllers, but how can i do the same for views?
I know i can implement a custom ViewEngine, but using reflector to look at the mvc default viewengine and its dependencies, it seems to go on and on and i'd rather not have to re-implement stuff thats already there. Has anyone got a cunning idea how to solve this?
I know i could make things easier with setter instead of constructor injection but id rather avoid that if possible.
Yes, if you are talking about the WebForms ViewEngine, you are correct in your assessment that it was not designed with inversion of control in mind. You can either lobby Microsoft to change it, or you can use setter injection. In FubuMVC, we use setter injection along with StructureMap's BuildUp method:
WebFormsControlBuilder creates
the instance of the view
StructureMapWebFormsControlBuilder
derives from WebFormsControlBuilder -
calls the base to create the
instance, and then calls BuildUp to
perform setter injection on all
applicable properites.
Related
I'm in a very specific situation where I'd like to override the default ASP.NET Core ControllerFactory. I'd like to do this because I want to be in full control of what type of controller I handle each request with.
The scenario is:
Request comes in with a specific subdomain
Based on this subdomain, I want to resolve a Generic type controller in the factory
For example:
category.website.com is called
We see it's of type category and will use the generic HomeController<T> , using DI to inject the category so the type is of HomeController<Category>
The HomeController<Category> will use some generic methods on type Category methods to render the homepage.
If I'm led to believe this link, a factory of type DefaultControllerFactory is registered on startup of the application. This seems to not be overridable.
Any idea how I would go by this? The most logical options for us is using the old ASP.NET MVC version which allows you to set your own ControllerFactory, but we'd lose features like being able to use SpaServices to prerender our Angular application.
Register your own implementation in ConfigureServices, after calling AddMvc:
services.AddSingleton<IControllerFactory, MyCustomControllerFactory>();
This way it will get called whenever a controller is to be built.
For completeness the best way is to actually implement an IControllerActivator and register it, since the default controller factory is not public. It will use whatever implementation of IControllerActivator is registered to actually create the controller class.
Due to limitations on the server side I need to build a self hosting web service in .NET...
I'm currently looking at HttpSelfHostServer but I'm very un-cool with it's magical construction of the controller, that seems to be, based on name alone and using only the default constructor.
For my tests I need to inject a value into the controller and using an IoC framework for this one usage where vanilla dependancy injection will suffice is over the top.
Is there any way I can do this with HttpSelfHostServer? or are there other, non-deprecated, self-hosting alternatives that give me control over my controller constructor calls.
The HttpSelfHostConfiguration instance that you need to provide to the HttpSelfHostServer constructor inherits the DependencyResolver property from the HttpConfiguration class. Hence, you can provide a custom dependency resolver as outlined here, for instance.
I was able to override IHttpControllerActivator in a unit test, I think it's similar to what you're trying to do.
e.g.
httpConfiguration.Services.Replace(typeof(IHttpControllerActivator),
Mock<IHttpControllerActivator>());
(there's more info. about services here)
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).
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.
I have a ViewModel class which I want to resolve via the unity ServiceLocator, but my viewModel requires a parameter to the constructor. The parameter's type is one of the entities in my application (a Customer object) rather than some service implementation. I know that coding against the Unitycontainer itself I can pass a paramater like this:
_container.Resolve<CustomerDetailViewModel>(new ParameterOverrides {{"customer", customer}});
but if I dont have direct access to the container I need to go via the ServiceLocator like this:
(CustomerDetailViewModel)ServiceLocator.Current.GetInstance<CustomerDetailViewModel>();
However using the second approach I have no way to pass in any parameters to the ServiceLocator. Is there any way this can be done? Is it "wrong" to get an instance of the Container from the ServiceLocator and then use that?
The problem is that you are trying to inject an entity (Customer in this case) into a class. Entities are short lived objects and they don't tend to be good candidates for being injected.
Instead of injecting a Customer, inject a ICustomerRepository service. You can register an ICustomerRepository implementation in the startup path of the application and this way you won't have to call the container directly, which makes the application design cleaner and the unit tests easier.
If you write a wrapper for the ServiceLocator you can hold the unity container within the wrapper and the expose an additional resolve method overload that takes the ParameterOverrides property. Then the method could use the unity container to do the resolution as per your first code snippet rather than the ServiceLocator code snippet.