I am using dependency injection for the inject interface with the classes
I use it in the Global.asax like this
new UnityContainer().RegisterType<IBookingService, BookingService>()
and controller
IBookingService bookingService
Now the thing is I want to change the injected implementation class for an interface in the controller level
How can I do it with a controller level?
i want to do some things like this in controller level
private readonly IBookingService bookingService;
if(countryCode = SE ){
bookingService = new bookingSE();
}
else IF (countryCode = NO ){
bookingService = new bookingNO();
}
i want to use Dependency injection for this
Make sure that you use the Unity.Mvc NuGet package. This will add a App_Start\UnityConfig.cs file to your project and you can add the registrations in its RegisterTypes method as follows:
container.RegisterType<IBookingService, BookingService>();
Perhaps you are already doing this, but I wanted to make sure since your exact code example with the new UnityContainer().RegisterType will not work.
Another interesting thing that this package does can be viewed in the App_Start\UnityWebActivator.cs file:
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
This line will register the unity container as standard MVC DependencyResolver. This allows constructor injection to be applied to your controllers. With this you can define your controller as follows:
public class MyCoolController : Controller
{
private readonly IBookingService bookingService;
public MyCoolController(IBookingService bookingService)
{
this.bookingService = bookingService
}
public ActionResult Index()
{
// your usual MVC stuff here.
}
}
In almost all cases, the use of constructor injection is advised over all forms of injection so stick with constructor injection unless there is no other way. And if you think there's no other way, please to ask here at Stackoverflow. We might be able to give some feedback on your code and design.
Just call Resolve
var bookingService= container.Resolve<IBookingService>()
Related
I'm trying to get my head around how one would unit test an ASP.NET MVC project that accesses data through a repository of some sort.
During the unit tests I'd obviously want to create a mock repository but how do I pass this mock repository to the Controller instance being tested? Also how would the actual repository, that's really connected to a database, find its way to the controller?
Do I simply do this through the constructors as I've shown below? I think this is how I should set up my controllers, but I'd like some confirmation that this is correct:
public class SampleController : Controller
{
private IRepository _repo;
//Default constructor uses a real repository
// new ConcreteRepo() could also be replaced by some static
// GetRepository() method somewhere so it would be easy to modify
//which concrete IRepository is being used
public SampleController():this(new ConcreteRepo())
{
}
//Unit tests pass in mock repository here
public SampleController(IRepository repo)
{
_repo = repo;
}
}
As everyone has already said, you'll want to use an IoC* or DI** container. But what they haven't said is why this is the case.
The idea is that a DI container will let you bypass ASP.NET MVC's default controller-construction strategy of requiring a parameterless constructor. Thus, you can have your controllers explicitly state their dependencies (as interfaces preferably). How those interfaces map to concrete instances is then the business of the DI container, and is something you will configure in either Global.asax.cs (live) or your test fixture setup (for unit testing).
This means your controller doesn't need to know anything about concrete implementations of its dependencies, and thus we follow the Dependency Inversion Principle: "High-level modules should not depend on low-level modules. Both should depend on abstractions."
For example, if you were to use AutoFac, you would do this:
// In Global.asax.cs's Application_Start
using Autofac;
using Autofac.Integration.Mvc;
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.Register<IRepository>(() => new ConcreteRepo());
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
// In your unit test:
var controllerInstance = new SampleController(new InMemoryFakeRepo());
// In SampleController
public class SampleController : Controller
{
private readonly IRepository _repo;
public SampleController(IRepository repo)
{
_repo = repo;
}
// No parameterless constructor! This is good; no accidents waiting to happen!
// No dependency on any particular concrete repo! Excellent!
}
* IoC = inversion of control
** DI = dependency inversion
(the two terms are often used interchangeably, which is not really correct IMO)
Yeah, you're correct, you pass it to your constructor like you have it. By mocking IRepository your explicitly ensuring that the database dependent code doesn't get into the controller for testing, like you want.
When you actually run it, you'll want to setup your application to work with an inversion of control container to enable those dependencies to be injected into your controller (some popular ones are Ninject, StructureMap, and Windsor).
Here's a sample of testing using Moq:
private Mock<IRepository> _mockRepo;
private SampleController _controller;
[TestInit]
public void InitTest()
{
_mockRepo = new Mock<IRepository>();
_controller = new SampleController(_mockRepo.Object);
}
[Test]
public void Some_test()
{
_mockRepo.Setup(mr => mr.SomeRepoCall()).Returns(new ValidObject());
var result = _controller.SomeAction() as ViewResult;
Assert.IsNotNull(result);
}
Now you can test your actions and mock your IRepository to behave however you want.
The best answer I know is to use an Ioc Container:
http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx
I prefer Castle Windsor
With the controller dependencies passed in you can then create mocks.
We have dependencies that implement interfaces which can be mocked.
For the real one, check out ninject mvc 3 on nuget, for unit testing I prefer to use fake objects with in-memory collections of known data
Here is the example code:
public interface IService<TEntity> {
IContext Context { get; set; }
//unimportant methods
bool Validate(TEntity entity);
void Add(TEntity enttity);
}
public class UsersController : Controller {
private IService<User> _service;
public MyController(IService<User> service){
_service = service;
_service.Context = ControllerContext;
}
}
I'm using AutofacControllerFactory to create controllers in my ASP.NET MVC app.
Is it possible to eliminate this line of code in every controller's constructor:
_service.Context = ControllerContext;
In other words: is it possible to automatically set this property with ControllerContext?
It should be possible because every IService implementation has a settable IContext property.
Should I extend the AutofacControllerFactory or is there a standard way of doint this?
What you have there is a Circular Dependency.
UsersController depends on IService<User>
IService<User> depends on ControllerContext
ControllerContext depends on UsersController
No DI Container can reach into your classes' innards and control what happens there. They can set up dependencies for you and inject them into your classes from the outside. However, they can't very well deal with circular dependencies, so a better option is to redesign the API.
From here it looks very much like the Context property of IService<TEntity> is a Leaky Abstraction. A Service shouldn't need to know anything about the UI framework in which it is running.
You can often break a circular dependency by changing one of the consumers to a more event-driven architecture.
Here's an article about this sort of problem.
Here's a related answer to a ASP.NET MVC question that looks a lot like yours: Is there a good/proper way of solving the dependency injection loop problem in the ASP.NET MVC ContactsManager tutorial?
See also the answer: Dependency-Injection to resolve circular dependencies
I'm new to Castle Windsor and am just using the latest version. I've created entries for my repositories which are working fine but I have one final dependency that I'm passing into my controller.
I've created a ModelStateWrapper which inherits from IValidationDictionary. The ModelStateWrapper takes a ModelStateDictionary in it's constructor so that in my code I can pass the following as an example:
IMembershipService _memSvc;
IValidationDictionary _validationService;
public AccountController()
{
_validationService = new ModelStateWrapper(this.ModelState);
_memSvc = new MembershipService(_validationService);
}
In my tests I can then do this using Moq:
var v = new Mock<ModelStateDictionary>();
_validationService = new ModelStateWrapper(v.Object);
_service = new MembershipService(_validationService);
I can't seem to get Castle to inject ModelState in with the ModelStateWrapper. I have no idea where to start and it seems I can't just 'ignore it' and try to manually inject as Castle is searching for dependencies and throwing me an error saying a dependency is remaining.
How do I configure Castle Windsor to use the ModelStateWrapper based off IValidationDictionary and also include ModelState as the constructor parameter?
Lloyd
It seems like you have a circular dependency (never a good thing). You can get around it by using an Abstract Factory as described in this very similar question.
However, although you may be able to solve the problem like this, it would be better to redesign the API to make the circular dependency go away. Circular dependencies often indicate a design flaw.
You're doing it wrong, and your wrongdoing has nothing to do with the container you're using.
Just do it like this, if you absolutely need to:
public AccountController(IValidationService service)
{
_validationService = service;
_memSvc = new MembershipService(_validationService);
}
then as you're registering your component, use an OnCreate method:
container.Register(
Component.For<AccountController>()
.WheveverEleseYouNeedHere()
.OnCreate((k, controller) =>
controller.ValidationService.Init(controller.ModelState)));
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.