WebApi with Unity issue with parameterless constructor - asp.net-mvc

I am trying to setup Unity for the first time in a WebApi project. I have added Unity.WebApi from Nuget and my UnityConfig file looks like this.
public static void RegisterComponents()
{
var container = new UnityContainer();
// register all your components with the container here
// it is NOT necessary to register your controllers
// e.g. container.RegisterType<ITestService, TestService>();
container.RegisterType<ApplicationDbContext>(
new InjectionFactory(c => new ApplicationDbContext()));
//container.RegisterType<ApplicationSignInManager>();
container.RegisterType<ApplicationUserManager>();
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}
However, if I try and call one of the default controllers, Account/Register I get an error saying ensure that I have a parameterless constructor.
I have looked at various articles that explain that the way Unity works in MVC and WebApi but as far as I can tell my config is correct? Im guessing Im missing something simple here as my installation works perfectly for constructor injection in an MVC project.

Unity will use the most greedy constructor (constructor with maximum number of parameters) when it tries to resolve your dependency, so in the case of the AccountController it has two constructors first one is parameterless and the second is with two parameters like bellow, and this what unity will try to use.
public AccountController(ApplicationUserManager userManager,
ISecureDataFormat<AuthenticationTicket> accessTokenFormat)
{
UserManager = userManager;
AccessTokenFormat = accessTokenFormat;
}
To override this, decorate required constructor with InjectionConstructorAttribute.
Hope that helps.

Related

Dependency injection with Global.asax

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>()

.NET MVC Service layer constructor

I'm interested how to implement my constructor in services. I'm a bit new to .NET so don't get me wrong if question is too trivial.
This are my current constructors but I would like to fully understand (since it looks like its working, I took code from somewhere)
// initialize UnitOfWork
private IUnitOfWork _unitOfWork;
public TownService()
: this(new UnitOfWork())
{
}
public TownService(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
What does : this means and which one is called first? Also I saw there is constructor with : base but I think thats the one thats calling superclass first.
Do I need to call new UnitOfWork() ? Isn't UnitOfWork supposed to be factory (shared) instance? Or it is factory and new UnitOfWork is not creating new but taking initialized one from memory?
Thanks.
Constructors in C#
Given your code
public TownService()
: this(new UnitOfWork())
{
//1
}
public TownService(IUnitOfWork unitOfWork)
{
//2
_unitOfWork = unitOfWork;
}
Invoking new TownService() will
Call the parameterless-constructor
Instantiate a new UnitOfWork and call the overload TownService(IUnitOfWork unitOfWork), so //2 is executed. This happens because of the this(...) call.
Then execute the parameterless constructor's body, i.e. //1
You need to get an instance of IUnitOfWork from somewhere, but calling the parameterless constructor which in turn will instantiate a new UnitOfWork probably isn't what you want - it doesn't really buy you much flexibility.
Using a factory
If you want to use a factory, you would go something like
ITownService s = new TownService(myFactory.Get<IUnitOfWork>());
thus avoiding the parameterless constructor.
Using IoC
If you want to use an IoC container, you would probably go something like this to configure your container
myContainer.Register<IUnitOfWork, UnitOfWork>(); //May need to provide database transaction or whatever
myContainer.Register<ITownService, TownService>();
You would also need to tell ASP.NET MVC to use the container when creating controllers. You do this by creating a ControllerFactory that is aware of your IoC container. Most IoC containers come with such a factory and instructions on how to use it.
Once that is done, you would be able to declare your controllers like
public class MyController
{
public MyController(ITownService townService)
{
/*...*/
}
}
and have ASP.NET MVC and your IoC container do the rest.

How should my ASP.NET MVC Controllers be aware of the repository

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

Can someone explain how Castle Windsor is working in my app?

I have begun using Castle Windsor and somehow my app is all up and running but I dont really understand how its working. Don't refer me to the documentation as I wouldn't be here otherwise.
In my Global.asax.cs I have this:
private static IWindsorContainer container;
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
BootstrapContainer();
}
protected void Application_End()
{
container.Dispose();
}
private static void BootstrapContainer()
{
container = new WindsorContainer()
.Install(FromAssembly.This());
var controllerFactory = new WindsorControllerFactory(container.Kernel);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
}
Now this is registering a new controller factory which I understand. The installation of a WindsorContainer from the current assembly I think registers all installers for example I have a repository installer. I assume that the container that is created in Global.asax is passed to the installers.
public class RepositoriesInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(AllTypes.FromThisAssembly()
.Where(type => type.Name.EndsWith("Repository"))
.WithService.DefaultInterface()
.Configure(c => c.LifeStyle.PerWebRequest));
}
}
In my controller I have created a constructor and passed in a IRepository argument. What I dont understand is how the controller accepts this argument.
Secondly as a test I created 2 repository classes that implement a IRepository. Putting a breakpoint in the controller constructor it passes in one of these classes. How do I map what class that implements IRepository should be passed to the constructor?
I also have Fluent NHibernate up and running. For the next stage I would like the IRepository to have a dependency on the ISession. How do I do that?
Thanks for your help
Since you have registered a controller factory that uses Windsor, it is the Windsor IoC container that is responsible for resolving all your controller instances as and when they are needed.
That is, when you access a URL in your MVC project that points to the action "Index" on your "HomeController" your WindsorControllerFactory will be asked, by the MVC framework, for an instance of HomeController.
If that controller has a constructor which takes an instance of IRepository and you have registered IRepository as a service with the container then Windsor will know how to satisfy the dependency of the HomeController class. Therefore it can first resolve IRepository into some concrete class, instantiate this, and pass it in as a parameter to the HomeController constructor before returning the instance of HomeController to the MVC framework.
If you need different implementations of IRepository for different purposes (i.e. a UserRepository and a ProductRepository) you could create separate interfaces for these, each of which extend IRepository, e.g.:
public interface IProfileRepository : IRepository {}
Then you can use Windsor's fluent registration API to register all concrete classes that implement IRepository, and have them registered by the specific service they provide, e.g. IProfileRepository.
If you do this, Windsor will automatically resolve all instances that implement IRepository for you without you having to write any new registration code when you add a new implementation.
As for making your repository classes depend on ISession, you can do this in a number of ways. I would recommend not letting them depend directly on a session, but rather let them depend on a class through which they can obtain the current session (so that you can share sessions between repositories). There's lots of information on why this is good practice out there on the web, just do a search.
Now, as for actually making it happen, you can either:
Register an instance of a class (by interface) that will retrieve a session for you with Windsor and let Windsor resolve this class as a parameter to your repository constructors.
Register ISession with Windsor and use a factory method to retrieve it when it is resolved.

IOC on IValidationDictionary with Castle Windsor

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)));

Resources