in tutorial Validating with a service layer constructor for Product Service looks like this:
ProductService(IValidationDictionary validationDictionary, IProductRepository repository)
and its instance in default controller constructor is created like this:
public ProductController()
{
_service = new ProductService(new ModelStateWrapper(this.ModelState), new roductRepository());
}
If I want to use Unity for DI, second constructor should obviously be used.
public ProductController(IProductService service)
{
_service = service;
}
But then I do not not know to configure Unity to inject first parameter of ProductServise,because ModelStateWrapper uses ModelState from controller, which is created inside controller and cannot be injected.Is it possible to inject such dependency to ProductService?
Think.
Here's what you're trying to do:
In order to create product controller you need product service
in order to create product service you need product controller
you have a vicious circle, that's why you can't do it.
I dunno about implementation Unity, but conceptually, you need to break the circle, like this:
create product controller without passing product service to it
create product service and pass product controller's model state to it
inject product service into product controller via property injection
AFAIK unity does support property injection, but it requires you to put attribute onto the property. If I were you, I'd consider using a less invasive container (pretty much any other is better).
Related
Following the ASP.Net 5 Getting Started document I see that because of dependency injection at the top of any controller that will access the database I need to put something like
private DbContext _Context;
public HomeController(DbContext Context)
{
_Context = Context;
}
to inject the DbContext into the controller for use. In my ASP.Net 5 MVC 6 Web App every single page will be interacting with the database so I thought I would create a BaseController that the reset of my controllers would inherit from and put the injection code there. I have done this but every controller that inherits from the BaseController give me the error
There is no argument given that corresponds to the required formal parameter 'Context' of 'BaseController.BaseController(DbContext)
I am new to DI and not sure if I am doing things right or even if it can be done the way I want to. Is it possible to do it this way or do I have to put that code on every controller I make, and if I do have to do that how can I write an action in the BaseController that interacts with the DB?
If your base controller has a constructor that takes DbContext then any controller that inherits it must also use the same constructor like this so it can pass the dependency to the base class:
public HomeController(DbContext Context):base(Context)
{
}
I've setup Unity in Bootstrapper.cs of my MVC application, all is working well for constructor injection on my controllers...
My question is when I'm in an ActionResult within a controller I need to get a reference to the container I previously created in Bootstrapper.cs so I can use it to resolve classes for me.
e.g:
public ActionResult Index()
{
//-- container needs a reference to unity container
var testService = container.Resolve<ITestService>();
return View(testService);
}
I need to get a reference to the container
No you don't. You should never need to reference the container (or the DependencyResolver) from within your application.
Use constructor injection instead:
public class HomeController : Controller
{
private readonly ITestService testService;
// constructor
public HomeController(ITestService testService)
{
this.testService = testService;
}
public ActionResult Index()
{
return View(this.testService);
}
}
Since you are using the MVC3 integration package for unity, you probably registered a Unity specific DependencyResolver in the startup path of your application. That looks much like this:
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
When you've done this, your custom DependencyResolver will delegate the creation of controllers to the Unity container and the Unity container is able to inject depdencies of the constructor's of the controllers.
The next thing you should never do is letting views do any work and making them dependent on your services. Views should be dumb and do nothing more than map the data they get from the controller and transform them to HTML (or JSON or whatever).
In other words, do not pass on the testService to the view. Calling the testService from within the view hides that logic, makes the view more complicated, and makes the system hard to test. Since you're using an ITestService abstraction, I assume you want to be able to test your code, but testing the view is not easy (or at least, not as easy as you can test the controller).
What you should do is let the controller call the testService and gather the data that is needed for the view to use. Than pass on that data (perhaps combined in a single class, a view model) to the view.
I have a HomeController and a Referrence of a type-class.If I create a new object of the class it works fine for me. But I dont want to create new object in the Controller instead I want to pass a referrence of the class through the HomwController's Constructor.Here is my code. I need to implement DI here.
//private readonly UnitOfWork<Student> _unitOfWork = new UnitOfWork<Student>();
private readonly UnitOfWork<Student> _unitOfWork;
//TODO ??
public HomeController(UnitOfWork<Student> unitOfWork)
{
_unitOfWork = unitOfWork;
}
public ActionResult Index()
{
return View(_unitOfWork.GenericRepository.GetAll());
}
Any help?
First, if you want to use dependency injection, you'll have to go through a third party dependency injection container - NInject or Unity for example among many others (or building your own if you are looking for some challenge).
Second, your HomeController should take an abstract unit of work type (interface or abstract class) as a parameter. You are actually using a concrete type in your HomeController constructor which is not how things should work in a dependency injection world (when using "Constructor Injection", your dependency container is in charge of providing the concrete implementation for the abstraction, based on container configuration).
Third your UnitOfWork<Student> does not make a lot of sense. A Repository<Student> would make some sense, but a Unit Of Work is not working on a single "Type" but rather on a "collection" of different data sets (a unit of work is potentially working on a collection of repositories). What would make sense here is to specify a parameter IUnitOfWork unitOfWork in your HomeController constructor, and configure your depency container to pass in a concrete UnitOfWork object on which you can get your Repository<Student> do operations on it in your action method (and potentially on other repositories accessed from the UnitOfWork object) and then Commit all modifcations by calling the associated method on the UnitOfWork object.
You should make some searches arround NInject use with ASP.NET MVC3 and also take a look at EntityFramework if you are dealing with UnitOfWork and Repository patterns (and if data is backed by a DB).
EDIT
In reaction to your comment dealing with (IUnitOfWork<Student> and IUnitOfWork<Course>).
As I said before, it does not make a lot of sense :
A UnitOfWork can be grossly seen as a "container" of repositories, giving access to these repositories and coordinating actions (like commiting all the changes) on these repositories. You should rather have an abstract non generic type IUnitOfWork, providing access to generic repositories such as IRepository<Student> or IRepository<Course>, and also containing a Commit method which would commit to DB (or file, or memory or whatever the unitofwork/repository implementation is targeting to persist data).
This way instead of injecting an IRepository<Student> and/or IRepository<Course> in your controller constructor (or if your controller needs to work on 10 different repositories, well, pass 10 parameters :S), you just accept a single parameter of abstract type IUnitOfWork (the concrete instance being injected by the DI container), and then any action method can work on any set of repository by getting them from the UnitOfWork, and once it has done all the changes, it can call Commit on the unitOfWork which will take care of comming all the modifications that have been done in the repository.
That's the theory and the general idea.
Now more specifically about DI in ASP.NET MVC, the more common way (there are other ways) of "plumbing" the DI container is to create a class inheriting from IDependencyResolver making use of the DI container to resolve types, and in Application_Start call DependencyResolver.SetResolver whith an instance of this class.
This way, when ASP.NET MVC is asked to create a controller (end user request), it will go through this depency resolver to ask for an instance of the controller, and this dependency resolver will turn to the DI container to create an instance of the controller by taking care of all needed injection.
You should take a look on the website / forums of your specific DI container as they all show ways to plumb it with ASP.NET MVC.
This is just a very high overview, there are a lot of tricky details, but that's the gross idea.
EDIT2
Just posted an article (my first one) on my blog to explain how to correctly use the Repository and UnitOfWork patterns in an ASP.NET MVC project.
http://codefizzle.wordpress.com/2012/07/26/correct-use-of-repository-and-unit-of-work-patterns-in-asp-net-mvc/
Are you talking ASP.NET MVC ?
I have been working with Ninject for some time now, and am very happy with it! Take a look at the sample app in this repository to get an idea on how to use it in ASP.NET MVC 3:
https://github.com/ninject/ninject.web.mvc/tree/master/mvc3
To expand a bit on the reply, here's a code snippet from where I set up the Ninject bindings
kernel.Bind(typeof(IUnitOfWork<>).To(typeof(UnitOfWork<>));
And my controller:
public class MyController : Controller {
private readonly IUnitOfWork<Student> uowStudent;
public MyController(IUnitOfWork<Student> uowStudent) {
this.uowStudent = uowStudent;
}
}
Then all you need to do, is make sure any arguments in the constructor for the UnitOfWork class are also bound in the kernel.
After listening to the Clean Code Talks, I came to understand that we should use factories to compose objects. So, for example, if a House has a Door and a Door has a DoorKnob, in HouseFactory we create a new DoorKnob and pass it to the constructor of Door, and then pass that new Door object to the constructor of House.
But what about the class that uses the House (say the class name is ABC)? It will depend on the HouseFactory, right? So do we pass the HouseFactory in the constructor of ABC? Won't we have to pass a whole lot of factories in the constructor that way?
Staying with the Door and DoorKnob example, you don't inject a factory - you inject the DooKnob itself:
public class Door
{
private readonly DoorKnob doorKnob;
public Door(DoorKnob doorKnob)
{
if (doorKnob == null)
throw new ArgumentNullException("doorKnob");
this.doorKnob = doorKnob;
}
}
No factories are in sight in this level.
House, on the other hand, depends on Door, but not on DoorKnob:
public class House
{
private readonly Door door;
public House(Door door)
{
if (door == null)
throw new ArgumentNullException("door");
this.door = door;
}
}
This keeps options open until at last you have to compose everything in the application's Composition Root:
var house = new House(new Door(new DoorKnob()));
You can use a DI Container to compose at this level, but you don't have to. No factories are involved.
If you inject too many factories that is a code smell called constructor over-injection that indicates your class is doing too much.
Many containers provide a feature called auto-factories. That means they generate factories of type Func<T>automatically if they know how to generate T.
Castle Windsor has an advanced feature called Typed Factory facilities which generates implementations of a factory interface on-the-fly.
There is also a port of typed factories for Unity in the TecX project.
If you end up using Unity, I have recently implemented an equivalent of Castle Windsor Typed Factories for Unity. You can find the project at https://github.com/PombeirP/Unity.TypedFactories, and the NuGet package at http://nuget.org/packages/Unity.TypedFactories.
The usage is the following:
unityContainer
.RegisterTypedFactory<IFooFactory>()
.ForConcreteType<Foo>();
You just have to create the IFooFactory interface with a method returning IFoo, and the rest is done for you by the library. You can resolve IFooFactory and use it to create IFoo objects straight away.
I am using an IoC container that uses constructor injection (Castle Windsor, for example). I have the following (example) class which manages a product...
public class ProductDataManager
{
public ProductDataManager(Product product, IProductDataLoader productDataLoader)
{
}
// a number of methods here that manage the products data in different ways...
}
It has a dependency on a Product which is only known by the classes consumer. It also has a dependency on a product data loader service. I define the implementer of this service in the IoC container.
How do I define this class (ProductDataManager) in the IoC container (and/or the consuming class) so that the service dependency (IProductDataLoader) can be injected by the IoC container and the data dependency (Product) can be passed by the consuming class?
Or is this a code smell? If so, how can this be modified?
You can use the TypedFactoryFacility and do something like this (off the top of my head)... first, define an interface for your abstract factory:
public interface IProductDataManagerFactory
{
ProductDataManager Create(Product product);
}
Register the factory like so:
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IProductDataManagerFactory>().AsFactory());
Now services can depend on IProductDataManagerFactory and have Windsor invoke container.Resolve through an automagically implemented factory.
Note that the parameter name product in the method signature must correspond to the parameter name in the ctor of ProductDataManager.