I did my research and I can’t find any specific example of what I want to do.
I successfully implement Ninject into me MVC project. Everything works perfect. However, I want to do a last step.
Until now, I have been working like this (normal DI pattern):
public class myController : Controller
{
private iMyInterface myRepository;
public myController(iMyInterface myRepository)
{
this.myRepository = myRepository;
}
public ActionResult list(){
return view(myRepository.getMyList())
}
// rest o the code ...
}
My Question is; there is a way to do something like this? (Repository “Generator”)
public class myController : Controller
{
private iMyInterface myRepository = specialClass.GetMyRepository();
public ActionResult list(){
return view(myRepository.getMyList()) }
// rest o the code ...
}
I aware I’m writing a nonsense code, but the idea is to be able to do something similar.
Any recommendation?
I don't know what specialClass is supposed to be, but this looks a lot like the Service Locator anti-pattern in action.
The first option where the repository is injected through the constructor is better, because it gives you more options, including using specialClass:
var controller = new myController(specialClass.GetMyRepository());
I don't know Ninject, but most DI Containers give you an option to map an interface to a method call that returns an instance of the interface.
I would rather take a repository "Generator" in a constructor. That would give you the same result, but with a correct injection.
Related
I am going to use SimpleInjector in MVC.5 application with WebAPI.2
Some methods of MVC controllers will create objects of repositories for CRUD operations.
Common approach on the Internet is a using interface of repository in MVC controller, like:
public class DashboardController : Controller
{
private readonly IDashboardRepository _repository;
public DashboardController (IDashboardRepository repository) {
_repository = repository;
}
[HttpPost]
public JsonData GetInfo()
{
return _repository.GetInfo();
}
...
Similar approach is recommended for WebAPI
However I would not like to pass IDashboardRepository into constructor of controller because of such reasons: I am sure that I will never mock implementation of repository. I do not need separate public interface for repository (current code base has no these interfaces and I'll need to change a lot of files to add them).
My repositories look like:
public class DashboardFunc : BaseFunc
{
public DashboardFunc(IApplicationStateProvider sp) :
base (sp)
{
}
public DashBoardData GetInfo()
{
...
I would like to use such code in controllers of MVC:
public class DashboardController : Controller
{
public DashboardController () {
}
[HttpPost]
public JsonData GetInfo()
{
DashboardFunc dashBoard = Global.MvcContainer.GetInstance<DashboardFunc>();
return Common.ToJson(dashBoard.GetInfo());
}
The same approach I would like for WebAPI controllers. The only difference is
DashboardFunc dashBoard = Global.WebApiContainer.GetInstance();
Is my modification (not using interface of repository in controller) of standard approach OK? Are there any potential issues that can arise in future that can lead architecture change?
Thank you!
Prevent falling back on calling Global.MvcContainer.GetInstance or any other form of Service Location
anti-pattern. There are a lot of downsides to this, even if you don't want to test that code. Downsides of using this are (among others):
You lose the ability for the container to change the given implementation for you; it makes your application less flexible.
You lose the ability for the container to diagnose the complete object graph for you.
You lose the ability to verify the configuration during app start or using an integration test.
You lose the ability to spot all the class's dependencies just by looking at a single line of code (the constructor).
So even when you don't need that interface, I would advice to still use constructor injection and do the following:
public class DashboardController : Controller {
private readonly DashboardFunc dashboard;
public DashboardController(DashboardFunc dashboard) {
this.dashboard = dashboard;
}
[HttpPost]
public JsonData GetInfo() {
return Common.ToJson(this.dashBoard.GetInfo());
}
}
I've implemented my UnitOfWork so that it keeps references to all repositories.
public interface IUnitOfWork
{
void Commit();
void RollBack();
}
public interface IMyUnitOfWork : IUnitOfWork
{
IFooRepository Foos { get; }
IBarRepository Bars { get; }
// Other repositories ...
}
Note that the repositories implements a generic type of repository interface.
public interface IFooRepository : IRepository<Entities.Foo>
{
// FooRepository specific methods goes here.
}
public interface IRepository<T> : IRepository
where T : class
{
}
Now how can I inject these repository to my UnitOfWork. Of course I want them with a lazy loading behavior. For example:
public class ConcreteUnitOfWork : IMyUnitOfWork
{
private readonly IUnityContainer unityContainer;
private IFooRepository fooRepository;
public ConcreteUnitOfWork(IUnityContainer unityContainer)
{
this.repositoryFactory = repositoryFactory;
}
public IFooRepository Foos
{
get
{
return this.fooRepository ??
(this.fooRepository = unityContainer.Resolve<IFooRepository>());
}
}
}
I know passing the Unity container to the UnitOfWork is incorrect but what pattern would you offer to solve this issue?
You may mention that I shouldn't keep the repository references in the UnitOfWork but please suppose a service class which needs several repositories. With this design I can just pass the UnitOfWork as the constructor parameter (Constructor Injection) to the service class, but if I didn't keep the repository references in UnitOfWork, I would have to pass all needed repositories as constructor parameters and you know what it leads to.
-- UPDATE --
Please let me know if I'm absolutely wrong and I should never compose the repositories in UnitOfWork. Then please give me a solution about "Constructor Over-injection" here.
-- UPDATE2 --
It seems that composing (referencing to) the repositories from UnitOfWork breaks the Open/Closed principle as we need to change the UnitOfWork class when we add a new repository (add a new property).
If it's right then I should consider a refactoring. Would you please give me some ideas?
It seems as though the current design proposal mixes more than one responsibility into the IMyUnitOfWork interface. You say that this is because otherwise a service class might need to take each Repository independently. I'm assuming you mean something like this:
public MyService(
IUnitOfWork uow,
IFooRepository fooRepository,
IBarRepository barRepository)
This seems to me to be a much simpler and cleaner design.
But then what about Constructor Over-injection?
Well, there's that... but the thing is that this is exactly the same problem you now have with your ConcreteUnitOfWork implementation. You haven't solved the Constructor Over-injection smell at all - you've just moved it to another class.
Actually, by moving it to ConcreteUnitOfWork you've made it more difficult to deal with the situation. Because ConcreteUnitOfWork is a pure infrastructure class (or a support class, if you will) it doesn't have any business context, so it's really hard to suggest a way resolve the Constructor Over-injection smell here.
On the other hand, a given Service (or perhaps a Controller) would tend to be more specialized and have knowledge of the business context, so it wouldn't need every repository in order to do its job - or if it does, it probably attempts to do too much.
Such a specific business component can better be refactored to a Facade Service.
I have a search form that can search in different provider.
I started out by having a base controller
public SearchController : Controller
{
protected readonly ISearchService _searchService
public SearchController(ISearchService searchService)
{
_searchService= searchService;
}
public ActionResult Search(...)
{
// Use searchService to query and return a view.
}
}
And child controllers
TwitterController : SearchController
{
...
}
NewsController : SearchController
{
...
}
I use StructureMap to insert all my dependencies in the controller. With this setup, I was able to change the SearchService depending on the type of the controller being instanciated.
x.For<ISearchService>().ConditionallyUse(o =>
{
o.TheDefault.Is.OfConcreteType<NewsSearchService>();
o.If(c => c.ParentType == typeof(TwitterController))
.ThenIt.Is.OfConcreteType<TwitterSearchService>();
...
});
That even allowed me to set different Views for each controller, (just putting the corresponding folder (Twitter, News...) and the Parent controller is still handling all the Search, with a simple
return View(results)
which is displaying the correct view specific to twitter, news, or other
Now that was cool and looked great, I a single form and the different views are displayed in tabs on the same page. That's where it starts to get complicated with this approach. The form has to post to /Twitter to search in twitter, to /News to search in news... which means I should change the action parameter of the form depending on which tab I am and display the correct tab on when the form returns depending on.. the url? craziness follows.
If you have built something like this already or know what's the best approach to this, please advices are welcome.
Now I think I would have less pain using a parameter in the form and posting to a single controller. I am thinking of injecting the correct SearchService depending on this parameter. What would be the best approach? I thought of using a model binder,
So I would have my ActionMethod that look like this:
public ActionResult Search(ISearchService service, Query query)
{
var results = service.Find(query);
}
But I think would need to make a call like this in the ModelBinder
ObjectFactory.GetInstance(...);
Based on the querystring parameter that describe which provider to use, and that doesn't seem more elegant to me. I feel stuck, help :(.
Whenever you need to vary a dependency based on a run-time value, Abstract Factory is the general solution.
Instead of injecting ISearchService into your Controllers, inject an ISearchServiceFactory:
public SearchController : Controller
{
private readonly ISearchServiceFactory searchServiceFactory;
public SearchController(ISearchServiceFactory searchServiceFactory)
{
if (searchServiceFactory == null)
{
throw new ArgumentNullException("searchServiceFactory");
}
this.searchServiceFactory = searchServiceFactory;
}
public ActionResult Search(...)
{
// Use searchServiceFactory to create an ISearchService based on
// run-time values, and use it to query and return a view.
}
}
It is not entirely clear to me which run-time value you need to vary on, but assuming that it's the Query, ISearchServiceFactory might be defined like this:
public interface ISearchServiceFactory
{
ISearchService Create(Query query);
}
I was trying to figure out how to use the abstract factory pattern and still let structuremap resolve all the dependencies of my components.
I believe that is the way I am going to implement it, but I submit this here to get some feedback if someone would read this.
As explain in the previous answer, I do not want to build the whole object graph depending on which provider I need in the Abstract factory.
ie :
class StatServiceFactory : IStatServiceFactory
{
public IStatService Create(string provider)
{
switch(provider)
{
case "blog":
return new StatService(IFacetRepository,ISearchManager,IConfigManager,BooleanQueryBuilder);
//How to resolve the Config, the SearchManager, and BooleanQueryBuilder?
//Add more abstract factories? It starts to get messy in my opinion...
}
}
}
What I can do is have the abstract factory use my container to create an instance of my search managers depending on a parameter (coming from the querystring in my case)
Structuremap allows to create named instances this way :
x.For<ISearchManager>().Use<AbcSearchManager>().Named("Abc");
x.For<ISearchManager>().Use<DefSearchManager>().Named("Def");
I need a way to inject the container in my Abstract factory.
I would probably wrap the container in a wrapper defined like this. That would keep me from leaking Structuremap into my project. I dont need more that those 2 features within the abstract factory anyway, but it is not necessary:
public interface IContainerWrapper
{
object GetInstance<T>();
object GetNamedInstance<T>(string key);
}
and the implementation :
public class ContainerImpl : IContainerWrapper
{
private readonly Container _container
public ContainerImpl(Container container)
{
_container = container;
}
...
}
And setup StructureMap to resolve dependencies to my abstract factory like that :
x.For<IContainer>.Use(new ContainerImpl(this));
x.For<IFactory>.Use<Factory>()
My factory would be then much simpler and would create my instance like that :
public class SearchmanagerFactory
{
private readonly IContainerWrapper _container;
public SearchmanagerFactory(IContainerProvider containerProvider)
{
_container = containerProvider;
}
public ISearchManager Create(string provider)
{
//eed to handle the bad input for provider.
return (ISearchManager)
_container.Resolve<ISearchManager>(provider);
}
}
That seems pretty clean this way :).
Thoughts?
This is more an extensive comment than an answer to explain why an AbstractFactory seems complicated. Here is something that looks closer from the reality:
class StatServiceFactory : IStatServiceFactory
{
public IStatService Create(string provider)
{
switch(provider)
{
case "blog":
return new StatService(IFacetRepository,ISearchManager,IConfigManager,BooleanQueryBuilder);
//How to resolve the Config, the SearchManager, and BooleanQueryBuilder?
//Add more abstract factories? It starts to get messy in my opinion...
}
}
}
The FacetRepository is the same for any provider, but the SearchManager changes, the ConfigManager changes, and the BooleanQueryBuilder is an abstract class with different implementation for different provider (because every API doesnt use the same keyword for their queries) All those dependencies are currently resolved by structuremap, based on the type of the controller.
I would really like to keep the benefit of StructureMap here, rather than using factories all the way, for each different pieces.'
Please see my edit at the end of my question for another suggestion to my problem.
If you don't know what I'm talking about either go through the tutorial and try to add dependency Injection yourself or try your luck with my explanation of the problem.
Note: This problem isn't within the scope of the original tutorial on ASP.NET. The tutorial only suggests that the patterns used are dependency injection friendly.
The problem is basically that there is a dependency loop between the Controller, the ModelStateWrapper and the ContactManagerService.
The ContactController constuctor takes an IContactManagerService.
The ContactManagerService constructor takes an IContactManagerRepository (not important) and an IValidationDictionary (which ModelStateWrapper implements).
The ModelStateWrapper constructor takes a ModelStateDictionary (which is a property called "ModelState" on the controller).
So the dependency cycle goes like this: Controller > Service > ModelStateWrapper > Controller
If you try to add dependency injection to this, it will fail. So my question is; what should I do about it? Others have posted this question, but the answers are few, different, and all seem kinda "hack-ish".
My current solution is to remove the IModelStateWrapper from the IService constructor and add an Initialize method instead like this:
public class ContactController : Controller
{
private readonly IContactService _contactService;
public ContactController(IContactService contactService)
{
_contactService = contactService;
contactService.Initialize(new ModelStateWrapper(ModelState));
}
//Class implementation...
}
public class ContactService : IContactService
{
private IValidationDictionary _validationDictionary;
private readonly IContactRepository _contactRepository;
public ContactService(IContactRepository contactRepository)
{
_contactRepository = contactRepository;
}
private void Initialize(IValidationDictionary validationDictionary)
{
if(validationDictionary == null)
throw new ArgumentNullException("validationDictionary");
_validationDictionary = validationDictionary;
}
//Class implementation...
}
public class ModelStateWrapper : IValidationDictionary
{
private readonly ModelStateDictionary _modelState;
public ModelStateWrapper(ModelStateDictionary modelState)
{
_modelState = modelState;
}
//Class implementation...
}
With this construct I can configure my unity container like this:
public static void ConfigureUnityContainer()
{
IUnityContainer container = new UnityContainer();
// Registrations
container.RegisterTypeInHttpRequestLifetime<IContactRepository, EntityContactRepository>();
container.RegisterTypeInHttpRequestLifetime<IContactService, ContactService>();
ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container));
}
Unfortunately this means that the "Initialize" method on the service has to be called manually by the controller constructor. Is there a better way? Maybe where I somehow include the IValidationDictionary in my unity configuration? Should I switch to another DI container? Am I missing something?
As a general consideration, circular dependencies indicate a design flaw - I think I can safely say this since you are not the original author of the code :)
I wouldn't consider an Initialize method a good solution. Unless you are dealing with an add-in scenario (which you aren't), Method Injection is not the right solution. You have almost already figured that out, since you find it unsatisfactory that you need to manually invoke it because your DI Container can't.
Unless I am entirely mistaken, the ContactController doesn't need the IValidationDictionary instance before its Action methods are being invoked?
If this is true, the easiest solution would probably be to define an IValidationDictionaryFactory interface and make the ContactController constructor take an instance of this interface.
This interface could be defined like this:
public interface IValidationDictionaryFactory
{
IValidationDictionary Create(Controller controller);
}
Any Action method on the controller that needs an IValidationDictionary instance can then invoke the Create method to get the instance.
The default implementation would look something like this:
public class DefaultValidationDictionaryFactory : IValidationDictionaryFactory
{
public IValidationDictionary Create(Controller controller)
{
return controller.ModelState;
}
}
How about slightly changing/improving the design to something like this: http://forums.asp.net/t/1486130.aspx
Each controller has a virtual method Initialize to do stuff like that.
I think there is no better way because the IValidationDictionary is an abstraction layer between you current request/controller/modelstate and the IContactService. Injecting controllers modelstate into the service and then injecting the service into the controller is simply impossible using constructor injection. One has to be first.
May be there is a way using property injection? But I think this will be complicated too.
I'm starting to get into Unit Testing, Dependancy Injection and all that jazz while constructing my latest ASP.NET MVC project.
I'm to the point now where I would like to Unit Test my Controllers and I'm having difficulty figuring out how to appropriately do this without an IoC container.
Take for example a simple controller:
public class QuestionsController : ControllerBase
{
private IQuestionsRepository _repository = new SqlQuestionsRepository();
// ... Continue with various controller actions
}
This class is not very unit testable because of its direct instantiation of SqlQuestionsRepository. So, lets go down the Dependancy Injection route and do:
public class QuestionsController : ControllerBase
{
private IQuestionsRepository _repository;
public QuestionsController(IQuestionsRepository repository)
{
_repository = repository;
}
}
This seems better. I can now easily write unit tests with a mock IQuestionsRepository. However, what is going to instantiate the controller now? Somewhere further up the call chain SqlQuestionRepository is going to have to be instantiated. It seems as through I've simply shifted the problem elsewhere, not gotten rid of it.
Now, I know this is a good example of where an IoC container can help you by wiring up the Controllers dependancies for me while at the same time keeping my controller easily unit testable.
My question is, how is one suppose to do unit testing on things of this nature without an IoC container?
Note: I'm not opposed to IoC containers, and I'll likely go down that road soon. However, I'm curious what the alternative is for people who don't use them.
Isn't it possible to keep the direct instantiation of the field and also provide the setter? In this case you'd only be calling the setter during unit testing. Something like this:
public class QuestionsController : ControllerBase
{
private IQuestionsRepository _repository = new SqlQuestionsRepository();
// Really only called during unit testing...
public QuestionsController(IQuestionsRepository repository)
{
_repository = repository;
}
}
I'm not too familiar with .NET but as a side note in Java this is a common way to refactor existing code to improve the testability. I.E., if you have classes that are already in use and need to modify them so as to improve code coverage without breaking existing functionality.
Our team has done this before, and usually we set the visibility of the setter to package-private and keep the package of the test class the same so that it can call the setter.
You could have a default constructor with your controller that will have some sort of default behavior.
Something like...
public QuestionsController()
: this(new QuestionsRepository())
{
}
That way by default when the controller factory is creating a new instance of the controller it will use the default constructor's behavior. Then in your unit tests you could use a mocking framework to pass in a mock into the other constructor.
One options is to use fakes.
public class FakeQuestionsRepository : IQuestionsRepository {
public FakeQuestionsRepository() { } //simple constructor
//implement the interface, without going to the database
}
[TestFixture] public class QuestionsControllerTest {
[Test] public void should_be_able_to_instantiate_the_controller() {
//setup the scenario
var repository = new FakeQuestionsRepository();
var controller = new QuestionsController(repository);
//assert some things on the controller
}
}
Another options is to use mocks and a mocking framework, which can auto-generate these mocks on the fly.
[TestFixture] public class QuestionsControllerTest {
[Test] public void should_be_able_to_instantiate_the_controller() {
//setup the scenario
var repositoryMock = new Moq.Mock<IQuestionsRepository>();
repositoryMock
.SetupGet(o => o.FirstQuestion)
.Returns(new Question { X = 10 });
//repositoryMock.Object is of type IQuestionsRepository:
var controller = new QuestionsController(repositoryMock.Object);
//assert some things on the controller
}
}
Regarding where all the objects get constructed. In a unit test, you only set up a minimal set of objects: a real object which is under test, and some faked or mocked dependencies which the real object under test requires. For example, the real object under test is an instance of QuestionsController - it has a dependency on IQuestionsRepository, so we give it either a fake IQuestionsRepository like in the first example or a mock IQuestionsRepository like in the second example.
In the real system, however, you set up the whole of the container at the very top level of the software. In a Web application, for example, you set up the container, wiring up all of the interfaces and the implementing classes, in GlobalApplication.Application_Start.
I'm expanding on Peter's answer a bit.
In applications with a lot of entity types, it is not uncommon for a controller to require references to multiple repositories, services, whatever. I find it tedious to manually pass all those dependencies in my test code (especially since a given test may only involve one or two of them). In those scenarios, I prefer setter-injection style IOC over constructor injection. The pattern I use it this:
public class QuestionsController : ControllerBase
{
private IQuestionsRepository Repository
{
get { return _repo ?? (_repo = IoC.GetInstance<IQuestionsRepository>()); }
set { _repo = value; }
}
private IQuestionsRepository _repo;
// Don't need anything fancy in the ctor
public QuestionsController()
{
}
}
Replace IoC.GetInstance<> with whatever syntax your particular IOC framework uses.
In production use nothing will invoke the property setter, so the first time the getter is called the controller will call out to your IOC framework, get an instance, and store it.
In test, you just need to call the setter prior to invoking any controller methods:
var controller = new QuestionsController {
Repository = MakeANewMockHoweverYouNormallyDo(...);
}
The benefits of this approach, IMHO:
Still takes advantage of IOC in production.
Easier to manually construct your controllers during testing. You only need to initialize the dependencies your test will actually use.
Possible to create test-specific IOC configurations, if you don't want to manually configure common dependencies.