I have a project setup with UnitOfWork Interfaces and Managers. All this works well while I just had to use an accountMananger for the base of my controller.
protected BaseController(IAccountManager acctManager)
{
_accountManager = acctManager;
}
and my controllers are created like this, and works.
public class AccountController : BaseController
{
public AccountController(IAccountManager accountManager)
: base(accountManager)
{
}
Now I am creating other business managers and I realise that by the end of the project my BaseController constructor is going to be huge or I am going to have a load of various signatures based on the controller I am on. And if I forgot something and needed another manager and changes one constructor, all the other controllers need to also change.
I mean, I actually ALWAYS want accountManager to be injected/resolved in the base. Can I do that? Since I am 99% checking for authorisation.
I have read about ControllerFactories but also somebody mentioned to implement IDependancyResolver , but no example, which is his preferred way to do it.
I can see this becoming a big burden to create constructors based on the controllers I need, which I dont have yet.
Can any body give me an example of how to easily access my managers in the base, as I need them. I mean, they all created and ready to be resolved anyway.. so why the heck do I need to pass them in such a strange way anyway?
Sorry. Just learning about DI and this is from a good tutorial but as you can see lacking some further explanation.
What you have with your account manager is called a Cross-Cutting Concern. There are a few different ways to skin this cat, but you should avoid injecting the same dependency into every controller.
In general, it is also better to avoid inheritance because that will cause tight coupling between your classes. The tight coupling is obvious here - what if you needed a controller that didn't have IAccountManager as a dependency later?
In this particular case, there is already a built-in loosely coupled authorization framework in MVC that you can utilize - the AuthorizeAttribute, which is the normal way of handling access to your controller action methods.
[Authorize]
public class AccountController : Controller
{
public AccountController () { . . . }
[AllowAnonymous]
public ActionResult Register() { . . . }
public ActionResult Manage() { . . . }
public ActionResult LogOff() { . . . }
}
There are also several other options for implementing cross-cutting concerns - implementing IActionFilter - see this for a DI friendly example, interception (which some DI containers support), using the Decorator Pattern, and putting the dependencies in ambient context (such as HttpContext.Items).
I can see this becoming a big burden to create constructors based on the controllers I need, which I dont have yet.
This is why you should inherit DefaultControllerFactory and provide it with the one instance of your DI container at application startup (in the composition root). It is typically the container's responsibility to provide the dependencies to your controllers, especially if your application is large.
public class AutofacControllerFactory
: DefaultControllerFactory
{
private readonly IContainer container;
public InjectableControllerFactory(IContainer container)
{
if (container == null)
throw new ArgumentNullException("container");
this.container = container;
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (requestContext.HttpContext.Request.Url.ToString().EndsWith("favicon.ico"))
return null;
return controllerType == null ?
base.GetControllerInstance(requestContext, controllerType) :
this.container.Resolve(controllerType) as IController;
}
}
I strongly recommend you read the book Dependency Injection in .NET. DI is one of the most misunderstood concepts in software development, and it is well worth the investment of studying the topic in detail on its own without having to sift through the misinformation on the Internet. There are many benefits to be gained by proper use of DI, but improper usage is often worse than not using DI at all.
Related
Hello, I'm trying to implement a ViewModelFactory "pattern" and I was wondering what's the best way to achieve it, considering the constraints of the current IoC container.
public class UserCreateViewModelFactory
{
private readonly DbContext db;
public UserCreateViewModelFactory(DbContext db){ this.db = db;}
public void Create(CreateUserViewModel viewModel)
{
//Creates the user
}
}
I have the above class easily injected into my controllers ctor. The head ache will come when I need more ViewModelBuilders, So I want to avoid two things:
Bloat ctor with injections
Bloat container with registrations
I want to be able to inject an IViewModelFactory on my controller and then using it like this:
[HttpGet]
public IActionResult GetUsers(int id)
{
return View(viewModelFactory.Build<GetUserViewModel>(id));
}
Notice that on calling Build(T) it has to call the correct IViewModelFactory implementation.
I know that StructureMap container support binding the concrete implementations to the corresponding interface but I'm trying to come up with a solution without having to add another dependecy to the project.
I think if you have builders for building viewmodels, then factory is extra layer of abstraction which simply can be dropped off.
Because you know the type of created viewmodel at compile time you can just inject a builder you need to the controller constructor.
If your controller create a lot of viewmodels and you end up with a lot of builders you need to inject - this can be considered as a sign of violation of Single Responsibility Principle. In that case you need to separate logic of controller to different controllers.
So I want to avoid two things:
Bloat ctor with injections
Separate class with bloated constructor to another classes with more specific responsibility which takes smaller amount of dependencies.
Or wrap dependencies with one or two, three classes based on their relation
Bloat container with registrations
This cannot be a problem, because dependency containers is usually designed to register whole "object graph" of your application
After sometime researching, I finally came up with a good solution for the this problem.
The solution is basically extending the default IoC capabilities through an IServiceCollection.ConnectImplementations() extension method.
During registration I'll search my concrete classes and connect them with its respective interfaces (like other containers). Then I use a Mediator/Proxy that has IServiceCollection injected and knows which concrete class should be building the view model.
The full solution is better explained by this gist I've created.
In the MVC application i am working with these days, they have registered and resolved all the Interface/Concrete class dependencies inside the controller itself. I read about ioc and dependency inversion and found that the thing that has been done is completely non-useful. Since it would anyway not allow the application to leverage benefits of IoC example mocking, unit testing and would also add cost of adding/resolving the dependencies unnecessarily. Below is code sample:
HomeController
using(IUnityContainer container= new UnityContainer())
{
container.RegisterType<IRepository1, Repository1>()
IRepository1 _repos1 = container.Resolve<IRepository1>();
}
I dont see any point of doing all this stuff if we dont get any benefit out of this. Can someone please tell if this could be of any use now or in future?
If not, i am planning to simply instantiate them with concrete implementations or like:
IRepository1 repos1= new Repository1();
Please ignore the syntax.
(I have editted the code snippet now.)
Using a container to first register and then resolve a concrete type doesn't make any sense, there is no benefit of that. You are still coupled to a concrete type. You could possibly argue that the container helps to match all constructor parameters with instances of respective types but this doesn't count as a real benefit in my opinion.
If you really don't plan to make use of abstractions that are resolved externally, then yes, you can safely remove the bloating container code and create concrete instances, just as you have presented.
The immediate answer to this question is your current implementation causes more overhead and performance impact then doing a standard construction, and you should remove it; or redesign your implementation of Unity.
The following is an example of the benefit of injection that occurs when resolving to a type that has a dependency of another type that is registered with the unity container.
public class UserService
{
internal readonly IRepository _repository;
public UserService(IRepository repository)
{
_repository = repository;
}
//Service Method that exposes 'Domain Logic'
public void CreateUser(string FirstName)
{
_repository.Insert<User>(new User() { FirstName = FirstName }); //Assumes there is a Generic method, Insert<T>, that attaches instances to the underline context.
}
public User GetUser(string FirstName)
{
return _repository.Query<User>().FirstOrDefault(user => user.FirstName == FirstName); // assumes there is a Generic method, Query<T>, that returns IQueryable<T> on IRepository
}
}
register the types (probably in a singleton pattern at Global.asax)
//Resolver is an instance of UnityContainer
Resolver.RegisterType<IRepository, Repository>(new ContainerControlledLifetimeManager());
Resolver.RegisterType<IUserService, UserService>();
Then the logic in your controller is like so:
var service = Resolver.Resolve<IUserService>(); //the resolver will resolve IRepository to an instance as well...
var user = service.GetUser("Grant");
I've got this app that uses Ninject for DI and I've got the following construction:
public class SomeServicHost
{
private ISomeService service;
public SomeServicHost(ISomeService service)
{
this.service = service;
}
public void DoSomething(int id)
{
// Injected instance
this.service.DoWhatever("Whatever");
// Without injection - this would be how it would be instantiated
var s = new SomeService(new Repo(id));
s.DoWhatever("Whatever");
}
}
interface ISomeService
{
void DoWhatever(string id);
}
class SomeService : ISomeService
{
private IRepo SomeRepo;
public SomeService(IRepo someRepo)
{
this.SomeRepo = someRepo;
}
public void DoWhatever(string id)
{
SomeRepo.DoSomething();
}
}
interface IRepo
{
void DoSomething();
}
class Repo : IRepo
{
private int queueId;
public Repo(int queueId)
{
this.queueId = queueId;
}
public void DoSomething()
{
// Whatever happens
}
So normal injection is not going to work. I'm going to need a factory. So I could do something like:
interface IServiceFactory
{
ISomeService GetService(int id)
{
return new SomeService(new Repo(id));
}
}
Which I acually have already. But if I do that, I lose all of the DI goodness, like lifecycle management, or swap out one implementation with another. Is there a more elegant way of doing this?
Keeping the factory as you describe it, seems fine to me. That's what they are for, when you have services that can only be instantiated at runtime depending on some runtime value (like id in your case), factory is the way to go.
But if I do that, I lose all of the DI goodness, like lifecycle
management, or swap out one implementation with another.
DI is not an alternative for factories. You need both worlds which lead to a flexible, loosely coupled design. Factories are for new-ing up dependencies, they know how to create them, with what configuration and when to dispose them, and if you want to swap implementations, you still change only one place: only this time it's the factory, not your DI configuration.
As a last note, you might be tempted to use the service locator anti-pattern, as proposed in another answer. You'll just end up with worse design, less testable, less clear, possibly tightly coupled with you DI container and so on. Your idea for using a factory is far better. (here are more examples, similar to yours).
Instead of doing
new SomeService(new Repo(id));
you can do
IResolutionRoot.Get<Repo>(new ConstructorArgument("id", id));
IResolutionRoot is the type resolution interface of the kernel, and you can have it constructor injected. This will allow you to benefit from the "DI goodness", as you called it. Please note that you might also want to use the ninject.extensions.contextpreservation extension.
The ninject.extensions.factory, that #Simon Whitehead pointed out already, helps you eliminate boiler plate code and basically does exactly what i've described above.
By moving the IResolutionRoot.Get<> call to another class (.. factory...) you unburden SomeService from the instanciation. the ninject.extension.factory does exactly that. Since the extension does not need an actual implementation, you can even save yourself some unit tests! Furthermore, what about if SomeService is extended and requires some more dependencies, which the DI manages? Well no worries, since you are using the kernel to instanciate the class, it will work automatically, and the IoC will manage your dependencies as it should.
If you wouldn't be using DI to do that instanciation, you might end up with using very little DI at the end.
As #zafeiris.m pointed out this is called Service Locator. And is also often called an anti pattern. Rightly so! Whenever you can achieve a better solution, you should. Here you probably can't. Suffice it to say it's better so stick with the best solution no matter what people call it.
There may be ways to cut down on the usage of service location. For example, if you have a business case, like "UpdateOrder(id)", and the method will create a service for that ID, then another service for that ID, then a logger for that ID,.. you may want to change it to creating an object which takes the ID as inheritable constructor argument and inject the ID-specific services and logger into that object, thus reducing the 3 factory/service locator calls to 1.
I just have a quick question. Im trying to use Unity with my asp.net MVC project. Im coming across a problem when using the Unit of Work pattern with an EF context.
Say i inject the uow in the constructor, but have 4 or 5 actions in the controller that need to use the UnitOfWork in a using statement. This isnt going to work! Because Id have to do a
new UnitOfWork() in each action method.
should i be injecting a UnitOfWork into each action method? or into just the constructor? or should I even be injecting this at all!! The problem im facing is that i want to be able to unit test my controller with Mock data, and i can only do this if I inject the UnitOfWork or the DBContext.
Inject factory instead. This way you still achieve separation of concerns and loose coupling, yet you won't face any issues with using statements:
private IUnitOfWorkFactory factory;
public MyController(IUnitOfWorkFactory factory)
{
this.factory = factory;
}
public ActionResult MyAction()
{
using (var uow = factory.CreateUnitOfWork())
{
// ...
}
}
Edit:
Natural advantage of such approach is its configurability - you can register whichever factory you like to serve different controllers and wire it up at composition root:
// Note: this isn't unity syntax, but I hope my point is clear
container.Register<ISessionFactory, ReusableSessionFactory>("Reusable");
container.Register<ISessionFactory, FreshSessionFactory>("Fresh");
container.Register<IController, LoginController>().With("Fresh");
container.Register<IController, HomeController>().With("Reusable");
Now,
LoginController will use factory that under the hood serves new session upon each request
HomeController on the other hand will reuse the same session for all its lifespan
It's worth noting that from the controller point of view, it's irrelevant which factory serves the session as it's a mere implementation detail. That's why we hide session factory dependency behind abstraction (interface in this example) and perform all the object-to-dependency binding at application's root.
If I understand correctly you simply want to be able to test the UOW with something like Moq?
In that case for good design principles and proper separation of concerns you should create a base context for your database that each repository class uses.
Then you should create a repository interface for each domain model entity. Then you can implement the interface in a seperate repository library (this way you can implement a POCO model)
Finally you either create a service layer between your domain objects and your action methods or just use the required repository interfaces within the action methods.
I answer it like this because it depends on your application infrastructure. If you have no service layer then the best practice is to do the following:
public class AccountController : Controller
{
private readonly IAccountRepository _accountrepository;
public AccountController(IAccountRepository repository)
{
_accountrepository = repository;
}
}
I hope this helps.
After much kicking and screaming, I'm starting to accept DI despite how much cleaner SL may seem as dependencies grow.
However, IMO there's still a significant show-stopper with regards to DI:
DI is not possible when you don't have control over an object's instantiation. In the ASP.NET world, examples include: HttpModule, HttpHandler, Page, etc.
In the above scenario we would resort to static service location to resolve dependencies, typically via HttpContext.Current, which invariably infers scope from the current thread. So if we're going to use static SL here, then why not use it else where too?
Is the answer as simple as: grit your teeth and use SL when necessary (like above), but try and favor DI? And if so: doesn't using static SL just once potentially break the consistency of an entire application? Essentially undoing the hard work of DI everywhere else?
Sometimes you just can't avoid tight coupling, like in your examples. However, that doesn't mean you need to embrace it either. Instead, quarantine it by encapsulating the messiness and factoring it away from your day-to-day life.
For example, if we want the current Forms Authentication user, we don't have much choice but to access HttpContext.Current.Request.User.Identity.Name. We do, however, have the choice of where to make that call.
HttpContext.Current is a solution to a problem. When we call it directly from where we use the results, we are declaring the problem and solution in the same place: "I need the current user name which is declared unwaveringly as coming from the current HTTP context." This muddles the definition of both and doesn't allow for different solutions to the same problem.
What we are missing is a clear articulation of the problem we are solving. For this example, it would be something like:
Determine the user which made the current request
The fact that we are using HttpContext.Current, or even a user name, is not a part of the core problem definition; it is an implementation detail that only serves to complicate the code requiring the current user.
We can represent the intent to retrieve the current user, sans implementation details, through an interface:
public interface IUserContext
{
User GetUser();
}
Any class where we called HttpContext.Current directly can now use this interface instead, injected by the container, to maintain DI goodness. It is also much more intention-revealing for a class to accept an IUserContext in its constructor than to have a dependency which can't be seen from its public API.
The implementation buries the static call in a single place where it can't harm our objects any more:
public class FormsUserContext : IUserContext
{
private readonly IUserRepository _userRepository;
public FormsUserContext(IUserRepository userRepository)
{
_userRepository = userRepository;
}
public User GetUser()
{
return _userRepository.GetByUserName(HttpContext.Current.Request.User.Identity.Name);
}
}
A good codebase is also one where the occasional restriction on the optimal solution is contained to a small area. The lack of possibility of DI partly explains the move from ASP.NET to the MVC counterpart. With HttpHandlers, I usually have a HttpHandler Factory which is the only class to get its "hands" dirty and instantiates HttpHandlers from a container.
Many DI containers have some kind of BuildUp method to perform setter injection on already instantiated objects. If you have service location, try to isolate it into some piece of your application that is purely an infrastructure concern. It will then act as a dampening field to the environment's limitations.
In short, some SL will not invalidate your efforts, but make sure the SL bits are infrastructural and well-contained.
To provide on #flq's answer with an example.
I'm working on an ASP.Net MVC project that makes rather extensive use of Ninject. There were a handful of places where I either couldn't use DI (Extension methods), or it was cleaner not to, and use SL instead (The base class for all of my controllers, constructor injection would make all the constructors for controllers messy).
So, as a compromise, I use a slight hybrid:
public interface IServiceLocator
{
T Create<T>();
}
public class NinjectServiceLocator : IServiceLocator
{
private readonly IKernel kernel;
public NinjectServiceLocator(IKernel kernel)
{
this.kernel = kernel;
}
public T Create<T>()
{
return kernel.Get<T>();
}
}
public class ServiceLocator
{
private static IServiceLocator current;
public static IServiceLocator Current
{
get
{
return current;
}
set
{
current = value;
}
}
public T Create<T>()
{
return current.Create<T>();
}
}
It may not be the best option, or a strict SL pattern, but it works for me. The additional interface lets me swap out the locator itself for testing. IKernel is Ninject's main DI object that gets configured, so substitute with your own framework, as most I've encountered have a similar core.
The typical approach in these cases is to write a generic infrastructure-level wrapper/adapter that does use Service Locator, but provides clean IoC for application-level classes that use this adapter.
I did this to enable IoC in HttpModules and Providers, two cases where the framework doesn't allow control of instantiation. A similar approach can be used for other similar entities.
The point here is that such wrapper/adapter code is part of your reusable infrastructure, and not your application-level code. What's generally not recommended is using service location in your application-level code.
The "BuildUp" feature that some containers offer are a poor workaround for these limitations. BuildUp doesn't allow you to regain control of instantiation, so you won't be able to use some container features such as proxying.