How do I get access to the target object when binding? - c#

I have the following Interface
interface IProfileRepo {
}
And it's implementation
public class DBProfileRepo : IProfileRepo {
string _specialValue;
public DBProfileRepo(IAuthorizedController authController) {
_specialValue = authController.SomeValue;
}
}
My binding is
Bind<IProfileRepo>()
.To<DBProfileRepo>()
.InRequestScope();
My MVC controller which implements IAuthorizedController, is receiving this injection of DBProfileRepo, however, DBProfileRepo requires this controller as a constructor argument. How can I do this?
I am using Ninject 2.2.1.0

You have circular dependency between your objects and this is something you should avoid when designing your object hierarchy. A repository should not require a controller instance, that simply doesn't make sense. A repository is a data access class which could be reused in different kind of applications such as Desktop or Silverlight where there are no controllers. It is the controller which should require a repository and that's pretty much all.
If you need to pass some information to this repository which is available only in the controller, like for example a request parameter, simply design an object and pass this object to the repository method from the controller but don't pass an entire controller.

Related

Best approach to pass database context from controller to model

I have read a lot of about IoC and design patterns but I´m not able to find clear answer. I´m doing whole data management in model, so I´m also creating database context in the model, but I found a solution from Benjamin Gale - When should I create a new DbContext(), which I like and it solves me a loft of problems with sharing db context, but my question is, how to pass this context from controller to model?
When I have ActionResult like this:
[Authorize, HttpPost]
public ActionResult AccountEditation(AccountEditationModel accountEditation)
{ ... }
Would be good solution to apply setter injection in AccountEditation actionResult, thats mean in each of actionResult method:
[Authorize, HttpPost]
public ActionResult AccountEditation(AccountEditationModel accountEditation)
{
accountEditation.db = Database; //Database from BaseController
...
}
Or is there any other way to do that?
Despite the name, ASP.NET MVC only loosely follows the MVC pattern. Namely, there's no true Model. Instead, your Model will be a combination of your entity, view models that represent that entity and your DAL, but each of these should be a separate thing. It's totally inappropriate to create or even inject a context into an entity class.
Your DAL will be the sole owner of the context. You should have an interface that represents an API that your application can use. Then, you should have one or more implementations of that interface, one per each discreet data access method (Entity Framework, Web Api, etc.). You'll then inject your context into this implementation and inject the implementation into your controller(s). The controllers, themselves, should only ever reference the interface. This is what's called the provider pattern, and it allows you sub-in different access methods as needed. Decided that you'd rather use Dapper than Entity Framework? Just create a new implementation for Dapper and inject that instead; none of the rest of your code needs to change.
The easiest thing I have found is to inject a repository into the Controller via Unity. And then pass the repository, if you need to, to whatever service or class you're using to process your business logic.
Basically...
public class AccountController : Controller
{
private IRepository<Account> _accountRepository;
public AccountController(IRepository<Account> accountRepository)
{
this._accountRepository = accountRepository;
}
}
When you use Unity and set it up properly, you can automatically inject whatever repository you're using into the AccountController class. After that, you shouldn't have a problem passing that same repository to other services or classes that need it.
Unity Dependency Injection

What is best way to pass injections to base controller when using C# StructureMap.Mvc5?

What is best way to get injections in base controller when using C# StructureMap.Mvc?
I can think of these 2 ways and don't know which is better.
From controller arguments to base controller arguments
(Nice approach but becomes a mess when there are many controllers with many properties to be injected)
Don't use child controller and initiate all injections using ObjectFactory.CreateInstance() in base controller constructor
(Very less code and manageable but not considered as good practice when Controller Injection is available)
thanks in advance.
I think bother approaches are fine and you can use the mix of both. Of course depending in the situation.
A. I believe if your child Controller require a dependency to be injected, then use the Constructor injection. This way you Controller's constructor API is explicit and it should state what has been injected into the Controller. Easy to read, and easy for discoverability. If you try to hide your DI types in a factory you lose this nice API/discoverability. Use property injection when the dependencies are optional if you think so. You don't really have pass these to the base Controller unless all your Child Controllers use them.
If you think you overloading the types in your Controller, try to aggreagate those interfaces to a single types.
B. It is not advisable to directly use the Structure map ObjectFactory in your Controller. Your Controllers should be agnostics of any infrastructure DI work. You can make use a generic factory (in infrastructure) to create types which uses the ObjectFactory within. If your DI types are required by the base Controller you may use this factory to resolve those types.
The ideas, inject types only when/where they need. Avoid injecting types to Controllers when they don't use/need.
Another option you available to you is setter injection via StructureMap's ObjectFactory.BuildUp() method.
It's worth mentioning that in StructureMap 3.1 the ObjectFactory has been deprecated in favour of injecting an instance of IContainer.
The examples would look like this:
StructureMap 3.0 and below:
public class BaseController {
protected IMyExampleServer MyExampleService { get; set; };
public BaseController() {
ObjectFactory.BuildUp(this);
}
....
}
StructureMap 3.1+:
public class BaseController {
protected IMyExampleServer MyExampleService { get; set; };
public BaseController(IContainer container) {
container.ObjectFactory.BuildUp(this);
}
....
}
Using StructureMap 3.1 would mean you'd only need to inject an instance of IContainer into your derived controller rather than each individual dependency that your base class requires.

ASP.NET MVC and Ninject - result action with interface parameter

kinda new to MVC, and kinda new with Ninject. Playing around...
I've defined ninject in my MVC application as follows:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind(
x => x.FromThisAssembly()
.SelectAllClasses()
.BindAllInterfaces()
);
}
I have controller with a form and this ActionResult:
public ActionResult Index(IMember Member)
{
return View();
}
and it's returning an error: "Cannot create an instance of an interface."
Now I understand that it might not like the interface but isn't Ninject supposed to inject the real class in there? do I need to put in the actual class? if so, doesn't that take the point out of using interfaces and building a lossly-cuppuled apps?
BTW in my Index.cshtml file I have the following as the first line:
#model IMember
Thanks
You seem to be confusing constructor dependency injection with action method parameters, they are not the same thing.
In your case you seem to want Ninject to somehow inject a concrete IMember implementation whenever a client (browser, etc) calls the Index action.
Bear in mind that any parameters that are going to be passed into an Action method are going to be coming from the client and not from the framework, so it wouldn't make sense to do this.
I am sure there is a hack you could do to make it work for e.g decorate the parameter with [Inject] or something but you've already lost at that point because you have just "revealed your sources" to the controller which is against the point of Inverting control - you might as well just pass the Ninject IKernel to the controller.
Anyway in your case, Ninject will only inject into the Controller constructor (assuming you have correctly wired it up) and in that respect, Doug's answer here is actually correct - if that IMember is some kind of controller dependency, then you must inject it into the constructor, and store it in for e.g. a private member so that you can later refer to it from within action methods.
If the IMember is not a controller dependency but is instead just a model-bound parameter that you want passed to your controller, then Dependency Injection is not the answer - the parameter should be coming from the caller.
Also, there might be another problem even if you do end up using constructor injection.
The convention-based binding you are using requires that there is a single class called Member that implements IMember, i.e that the class name differs from the interface name only by lack of the initial "I". If this isn't the case for your class, then the convention-based binding will not work anyway and you need to use something explicit like
kernel.Bind<IMember>.To<MyMemberImplementationClassName>();
Hope that helps.
Is your RegisterServices method in the NinjectWebCommon.cs file located in the App_Start folder?
You'll also need to pass the Member object into the view kind of like below:
public class HomeController : Controller
{
private IMember _member;
public HomeController(IMember member)
{
_member = member;
}
public ActionResult Index()
{
return View(_member);
}
}

MVC Unit Testing with Unity Container

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.

MVC Controller Generic injection with AutoFac

I am fairly new to DI with Autofac and wonder if the following is possible
I want to create a generic controller and action that receives an
injected type.
I do not want an instance of the injected type, but just need its
type, which would be an inplementation of an expected interface.
I would also like to pass that generic type on to a ViewModel, but that is another subject altogether, however if some genious out there can solve both that would be excellent.
public ContractorController<T> : Controller
where T : IContractor{
public ViewResult New() {
var vNewModel = new NewViewModel<T>();
return View(vNewModel);
}
}
This controller should be called through
http://mysite.com/Contractor/New
I have been looking into registering generics with AutoFac, but it
seems that the problem is that the AutofacControllerFactory only implements GetControllerInstance(), expecting the controller Type passed to it from either GetController() or CreateController(), not sure which or what the diffirence is between them. These methods receive the controller's name as a string from RoutData and return the corresponding .NET type which, give the url, http://mysite.com/Contractor/New is controller=Contractor and thus ContractorController cannot be matched by GetController() or CreateController() and therfore passing null to GetControllerInstance() which mean AutofacControllerFactory does not attempt to resolve the type.
I figured that I would have to create a custom Controller Factory
deriving from AutofacControllerFactory, override GetController() or CreateController() and
perform my own mapping from the controller names to the generic types.
Something like
if (controllerName == "Contractor")
return System.Type.GetType(
"UI.Controllers." + controllerName + "Controller`1");
When I debug this I can see that this code is finding the generic controller and returning it.
I thought I could then just register the types like
builder.RegisterType<FakeContractor>().As<IContractor>();
builder.RegisterGeneric(typeof(ContractorController<>));
But I am getting the following error
The Autofac service
'UI.Controllers.ContractorController`1'
representing controller
'ContractorManagement.UI.Controllers.ContractorController`1'
in path '/Contractor/New' has not been registered.
So I think I may be barking up the wrong tree.
Can anyone please shed some light on how I can do this without pulling
my teeth
Thank you
I'm not entirely sure why you want a controller using a generic. Using a generic on a Controller isn't really supported in Mvc - or at least the supporting routing path would be involved. Perhaps you can provide more info on the reasoning behind the approach?
What it looks like is that you want a controller that supports model binding against varying types. The next question is whether these types vary across a common interface or base class.
If that's the case, for Mvc2 check out the IocModelBinder information. This will work with Autofac quite well. This will allow the type to be model bound on post or get allowing you to inject services with autofac.
If you want to vary the types by a common base - supporting a variety of concrete view model - then check out the DerivedTypeModelBinder in MvcContrib. There is a version that works in Mvc 1, 2 and now MvcContrib for Mvc3 has a good sample app to accompany it. The Mvc3 implementation is also faster - speed wasn't a problem before, it's just a more efficient identification process.
Maybe it's not a direct answer to your question, but this is the only possible way to use generic controllers that I ever seen and used:
public abstract class ContractorControllerBase<T> : Controller where T : IContractor {
public ViewResult New() {
var vNewModel = new NewViewModel<T>();
return View(vNewModel);
}
}
public class FakeContractorController : ContractorControllerBase<FakeContractor> {
}

Categories