I'm trying out Dynamo IoC with the web extensions for Mvc, and I see they've done a great work creating a custom HttpApplication to derive your Global.asax from. However it seems I'm missing something.
I want to accomplish DI in my controllers, but I'm stuck with the usual "The controller must have a parameterless constructor" problem.
This is what I do in my global.asax (which derives from DynamoMvcAndWebApiApplication):
protected override void RegisterDependencies(Dynamo.Ioc.IIocContainer container)
{
container.Register<ILogger, FakeLogger>();
}
Then my controller:
public class HomeController : Controller
{
private readonly ILogger logger;
public HomeController(ILogger logger)
{
this.logger = logger;
}
public ActionResult Index()
{
logger.Log("test");
return View();
}
}
This gets me the "no parameterless constructor error". I thought the web extensions of Dynamo already took care of whatever was required to make DI work.
If I add a parameterless constructor it gets called, but then my ILogger will be null, and I'll get a NullReferenceException in my action method.
I thought about having to implement a ControllerFactory but I also thought that if it was mandatory they would have provided it along with all other stuff for MVC, so I think that I am misusing what is provided.
I'd like to know if anyone knows how to make DI work in this scenario. Thanks.
My best guess is that it is because you don't register the HomeController when registering the dependencies.
According to your example you don't.
I agree with MartinF. If you want your HomeController's dependencies to be resolved, you need to instantiate it by resolving it from your Dynamo container. Granted, I'm not seeing your resolve code, but I'm just guessing that's what's going on. I don't think it's a matter of "Dynamo doesn't fully integrate with MVC". Depending on how the container works, you may not even need to explicitly register HomeController with the container before trying to resolve it, but you DO need to ask the container to resolve it for you so that it may satisfy the dependencies. Just my guess based on the usage of other containers.
After a long digging and experimenting, it just seems that Dynamo doesn't fully integrate with MVC. I tried Ninject integration with MVC and it works fine, out of the box.
My guess is that Dynamo is just "not there yet", I'll keep checking on its updates in the future.
Related
If I wish to inject my DbContext into one of my controllers as follows:
public class HomeController : Controller
{
MyDbContext _db;
public HomeController(MyDbContext db)
{
_db = db;
}
...
}
What is the correct way to configure this with Unity. The context would have to intantiated per request so PerRequestLifetimeManager seems like the natural choice. But from reading this documentation it seems that PerRequestLifetimeManager is advised against. The terms "thread-unsafe dependencies" make me nervous about using it as do the warning about it causing "bugs in the end user’s application code". The warnings seem to be very vague though so that it is not clear what the dangers actually are. Can anyone give examples of the kind of bugs that can occur from the use of PerRequestLifetimeManager? And if this lifetime manager is advised against, what would be a better way to inject the DbContext into my controllers?
I am creating one demo application to learn how to use repository pattern for performing Insert operation.I am using Nop Commerce**(http://www.nopcommerce.com) **code for repository pattern
Error:No parameterless constructor defined for this object
I have seen this link:MVC: No parameterless constructor defined for this object
This is my Structure:
My Repository interface:
public partial interface IRepository<T>
{
void Insert(T entity);
}
My Service Layer:
public partial interface IEmployeeService
{
void InsertCategory(EmployeeMaster employeeMaster);
}
My Class which will implement that interface(service):
public partial class EmployeeService : IEmployeeService
{
#region Fields
private readonly IRepository<EmployeeMaster> _employeeMasterRepository;
#endregion
#region Ctor
public EmployeeService
(
IRepository<EmployeeMaster> employeeMasterRepository
)
{
this._employeeMasterRepository = employeeMasterRepository;
}
#endregion
public virtual void InsertCategory(EmployeeMaster employeeMaster)
{
if (employeeMaster == null)
throw new ArgumentNullException("employeeMaster");
_employeeMasterRepository.Insert(employeeMaster);
}
This is my controller:
public class HomeController : Controller
{
#region Fields
private readonly IEmployeeService _employeeService;
#endregion
#region Constructors
public HomeController
(
IEmployeeService employeeService
)
{
this._employeeService = employeeService;
}
#endregion
Getting Error:No parameterless constructor defined for this object
I have studied regarding this error and all the sources are saying that use Dependency injection to solve this error.
Can anybody guide me how to use dependency injection to solve this error??
Maybe you're taking as a sample a project that is too complex for you at this moment. Nopcommerce is a big and full featured product that has a lot of elements, so it easy to get lost. Not the best sample to learn how the repository pattern works, but I certainly recommend you to check it again once you have the basic concepts clear to see them used in a real scenario.
NopCommerce uses Autofac for dependency injection, a very popular IoC container. You can look for a class called DependencyRegistrar in the project Nop.Web.Framework to see how it is used, if you're curious about it. You can get more examples on how to use dependency injection with Autofac in their repository and their getting started guide.
My recommendation is to look for an easier to follow example. For starters, any of the popular IoC containers will be OK until you have your own criteria to choose one. For instance you can follow the Autofac's guide for MVC
You're correct - you'll need to use something like Unity, Ninject or Autofac to get this running.
Essentially - the steps are roughly the same regardless of the tech used.
Using unity as an example:
1) In your MVC project, use NuGet to add "Unity Bootstrapper for MVC". (right click references, manage nuget packages, search for unity online, select "Unity Bootstrapper for MVC"
This will add a few things to your project - the most interesting is the unityConfig.cs in App_start.
2) In unityConfig.cs - find RegisterTypes method
RegisterTypes is where you tell the unity container "when you need one of X, use implementation Y" - in your case "when you need an IEmployeeService, use EmployeeService"
3) In register types - add your type mappings - for example, in your case:
container.RegisterType<IEmployeeService, EmployeeService>();
AND
4) Bit more complicated: as you have IRepository and you need this to resolve your employeeService correctly you'll also have to register a generic type against a generic implementation (it's a little odd). Looking at your types, it's going to be something like:
container.RegisterType(typeof(IRepository<>), typeof(Repository<>));
(You'll need to resolve the namespaces according to your projects).
So - what this is saying is...
Right MVC - when you need an IEmployeeService use employeeService, and
when you need an IRepository<>, use Repository<>
Now - because of the webActivator that was added during the NuGet installation (right next door to UnityConfig.cs), that should be it - the webActivator sets the DependencyResolver.Current to something that uses this unityContainer.
Beacause of this, MVC will now use this new unityContainer whenever it tries to instantiate your controllers, resolving the type mappings on the way.
The webActivator and unityConfig classes do alot of the heavy-lifting for you, just elaborate registerTypes and you should at least have a foot-hold in the solution.
HTH - good luck.
PS - DI itself is a massive subject - far too much for here, you'll bump into all sort of weird and wonderful things (supplying Ctor args for resolutions, lifetime management just for a start!) - it's fun, but not trivial, so you'll have to excuse me if this doesn't work "out of the box" (it's almost impractical to think it would) - this is merely just a vague attempt to give you a foothold in the subject!
For more info on unity - I suggest you read up here (Dev guide to using Unity on MSDN)
I have an MVC3 application that is using Ninject and MvcSiteMapProvider.
I have created this class which MvcSiteMapProvider uses to dynamically add nodes to my sitemap:
public class PageNodeProvider : DynamicNodeProviderBase
{
public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
{
// need to get repository instance
var repository = // how do I get this???
foreach (var item in repository.GetItems())
{
yield return MakeDynamicNode(item);
}
}
}
The MvcSiteMapProvider instantiates this type itself, so I'm not sure how to inject my repository into it.
I thought about using service location by getting a handle on my kernel and calling Get<Repository>() in the method. But, I saw this property when looking at the definition of NinjectHttpApplication:
// Summary:
// Gets the kernel.
[Obsolete("Do not use Ninject as Service Locator")]
public IKernel Kernel { get; }
Do not use Ninject as Service Locator ?! How else am I supposed to do this?
I then found this question here on stackoverflow and all answers say don't use Service Location.
What am I supposed to do?
This seems to be another chapter from the book "Why providers are bad design?". You have the same problem as with any kind of ASP.NET providers. There are no really good and satisfying solutions for them. Just hacks.
I think the best option you have is to fork the project and change the DefaultSiteMapProvider to use DepencencyResolver instead of the Activator and provide the implementation back to the community. Then you can use constructor injection in your PageNodeProvider implementation. This will solve the problem once for all types and everyone.
Of course you could also use the DependencyResolver just in your implementation. But this is by far not the best solution because you should get the instances as close to the root as possible, it makes testing more complicated and it solves the problem just for you.
Even though I see that you've decided to ditch the provider altogether, I'd like to elaborate on using the DependencyResolver. Basically, you can manually get the correct repository instance via Ninject using
var repository = DependencyResolver.Current.GetService<IRepository>();
This is less robust, as you have to maintain this as well as the NinjectMVC3.cs class should the stuff change, and it is a bit more complicated to test.
I'm practicing DDD with ASP.NET MVC and come to a situation where my controllers have many dependencies on different services and repositories, and testing becomes very tedious.
In general, I have a service or repository for each aggregate root. Consider a page which will list a customer, along with it's orders and a dropdown of different packages and sellers. All of those types are aggregate roots. For this to work, I need a CustomerService, OrderService, PackageRepository and a UserRepository. Like this:
public class OrderController {
public OrderController(Customerservice customerService,
OrderService orderService, Repository<Package> packageRepository,
Repository<User> userRepository)
{
_customerService = customerService
..
}
}
Imagine the number of dependencies and constructor parameters required to render a more complex view.
Maybe I'm approaching my service layer wrong; I could have a CustomerService which takes care of all this, but my service constructor will then explode. I think I'm violating SRP too much.
I think I'm violating SRP too much.
Bingo.
I find that using a command processing layer makes my applications architecture cleaner and more consistent.
Basically, each service method becomes a command handler class (and the method parameters become a command class), and every query is also its own class.
This won't actually reduce your dependencies - your query will likely still require those same couple of services and repositories to provide the correct data; however, when using an IoC framework like Ninject or Spring it won't matter because they will inject what is needed up the whole chain - and testing should be much easier as a dependency on a specific query is easier to fill and test than a dependency on a service class with many marginally related methods.
Also, now the relationship between the Controller and its dependencies is clear, logic has been removed from the Controller, and the query and command classes are more focused on their individual responsibilities.
Yes, this does cause a bit of an explosion of classes and files. Employing proper Object Oriented Programming will tend to do that. But, frankly, what's easier to find/organize/manage - a function in a file of dozens of other semi-related functions or a single file in a directory of dozens of semi-related files. I think that latter hands down.
Code Better had a blog post recently that nearly matches my preferred way of organizing controllers and commands in an MVC app.
Well you can solve this issue easily by using the RenderAction. Just create separate controllers or introduce child actions in those controllers. Now in the main view call render actions with the required parameters. This will give you a nice composite view.
Why not have a service for this scenario to return a view model for you? That way you only have one dependency in the controller although your service may have the separate dependencies
the book dependency injection in .net suggests introducing "facade services" where you'd group related services together then inject the facade instead if you feel like you have too many constructor parameters.
Update: I finally had some available time, so I ended up finally creating an implementation for what I was talking about in my post below. My implementation is:
public class WindsorServiceFactory : IServiceFactory
{
protected IWindsorContainer _container;
public WindsorServiceFactory(IWindsorContainer windsorContainer)
{
_container = windsorContainer;
}
public ServiceType GetService<ServiceType>() where ServiceType : class
{
// Use windsor to resolve the service class. If the dependency can't be resolved throw an exception
try { return _container.Resolve<ServiceType>(); }
catch (ComponentNotFoundException) { throw new ServiceNotFoundException(typeof(ServiceType)); }
}
}
All that is needed now is to pass my IServiceFactory into my controller constructors, and I am now able to keep my constructors clean while still allowing easy (and flexible) unit tests. More details can be found at my blog blog if you are interested.
I have noticed the same issue creeping up in my MVC app, and your question got me thinking of how I want to handle this. As I'm using a command and query approach (where each action or query is a separate service class) my controllers are already getting out of hand, and will probably be even worse later on.
After thinking about this I think the route I am going to look at going is to create a SerivceFactory class, which would look like:
public class ServiceFactory
{
public ServiceFactory( UserService userService, CustomerService customerService, etc...)
{
// Code to set private service references here
}
public T GetService<T>(Type serviceType) where T : IService
{
// Determine if serviceType is a valid service type,
// and return the instantiated version of that service class
// otherwise throw error
}
}
Note that I wrote this up in Notepad++ off hand so I am pretty sure I got the generics part of the GetService method syntactically wrong , but that's the general idea. So then your controller will end up looking like this:
public class OrderController {
public OrderController(ServiceFactory factory) {
_factory = factory;
}
}
You would then have IoC instantiate your ServiceFactory instance, and everything should work as expected.
The good part about this is that if you realize that you have to use the ProductService class in your controller, you don't have to mess with controller's constructor at all, you only have to just call _factory.GetService() for your intended service in the action method.
Finally, this approach allows you to still mock services out (one of the big reasons for using IoC and passing them straight into the controller's constructor) by just creating a new ServiceFactory in your test code with the mocked services passed in (the rest left as null).
I think this will keep a good balance out the best world of flexibility and testability, and keeps service instantiation in one spot.
After typing this all out I'm actually excited to go home and implement this in my app :)
I'm trying to implement my custom authorize attribute like:
public class MyCustomAuth : AuthorizeAttribute
{
private readonly IUserService _userService;
public MyCustomAuth(IUserService userService)
{
_userService= userService;
}
... continued
}
I am using Castle Windsor for automatically resolve the dependency.
When I try to use it as an attribute of an action method obviously I am asked to pass the parameter or I need to have a parameter-less constructor that should resolve in some way it's dependency.
I tried to inject the dependency with a property but Windsor is not injecting it.
The only option I see now would be to instantiate manually the concrete object dependency loosing the benefit of Windsor.
How would you solve this problem?
You cannot use DI with attributes - they're metadata;
public class MyCustomAuth : AuthorizeAttribute
{
public void OnAuthorization(...)
{
IUserService userService = ServiceLocator.Current.GetInstance<IUserService>();
}
}
Learn about Windsor/ServiceLocator here.
See similar question here.
You can use a custom ControllerActionInvoker and inject property dependencies (you can't do constructor injection because the framework handles instantiation of attributes). You can see a blog post I just did on this technique.
You did not supply any castle code or configuration examples. Therefore, I am assuming you are new to castle and unfimilar with the registration process.
First of all, any object you want to act upon must come from Castle Windsor via a registered type. With that said, you are going down the wrong path by trying to use castle windsor with attributes - because attributes are not referenced in code, but instead are reflected upon. Therefore, there is not a place for IoC (Castle Windsor in this case) to create the object.
I say this, because what you are trying to accomplish has already been done via different means. First of all, put your dependency injection on your controllers.
public class PostController
{
private IUserService _userService;
public PostController (IUserService userService)
{
_userService = userService;
}
// other logic
}
For Castle to work, you have register all types. So, you have to register IUserService, and what services implement that interface, within Castle Windsor. You can do this via a manual process in your global.asax with container.AddComponentWithLifeStyle; or the more preferred method is to use a configuration file.
Using a configuration file, your IUserService would look something like this:
<?xml version="1.0" encoding="utf-8" ?>
<castle>
<components>
<!--lifestyle="singleton|thread|transient|pooled|webrequest|custom"-->
<component
id="UserService"
service="MyMvcProject.IUserService, MyMvcProject"
type="MyMvcProject.UserService, MyMvcProject"
lifestyle="transient">
</component>
</components>
</castle>
MyMvcProject is the name of your project and make sure to use the exact namespace and fully qualified name of the interface, and type. Please give code samples of your actual namespaces, else we cannot help you any further.
Before that will work, you will need to modify your app.config or web.config to register the searchGroup for Castle Windsor:
<configSections>
<section name="castle"
type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor"/>
</configSections>
<castle configSource="castle.config"/>
Now that you are all registered and setup, it is time to tell your MVC application to "Use Castle Windsor to create each instance of my Controllers." Doing this means that Castle Windsor, being an Inversion-of-Control (aka IoC) container, will inspect the dependencies of your controller and see that it depends on IUserService and implement an instance of UserService. Castle will look into its configuration of registered types and see that you have registered a service for IUserService. And, it will see in your configuration file that you want to implement the concrete class of UserService that implements IUserService. So, the IoC container will return UserService when a dependency on IUserService is requested.
But before that can happen, you have to tell your MVC application to use your configuired IoC container. You do this by registering a new ControllerFactory. To do that, see my answer over at this question:
Why is Castle Windsor trying to resolve my 'Content' and 'Scripts' folder as a controller?
And notice the global.asax part of how to register that code. It works quite well!
Now, when all of that is said and done, you want to authorize a user. Use the normal [Authorize] that implements Forms Authentication, and use your _userService to grab any user details of the signed in user.