Advice on Ninject Implementation - dependency-injection

I'm developing my first project using Ninject (an MVC web application) and have a question regarding the correct/best use on Ninject.
I have set up a NinjectModule that binds an interface to a concrete class, but now I want to create instances of the interface object within my code. To achieve this I have written the following method:
public class NinjectControllerFactory : DefaultControllerFactory {
private class MyServices : NinjectModule {
...
}
public static IMyRepository GetMyRepository()
{
IKernel kernel = new StandardKernel(new MyServices());
return kernel.Get<IMyRepository>();
}
}
and this seems to work fine...
IMyRepository tempDB = ControllerFactory.GetRoomarRepository();
My question is, this the right/best way to achieve the result I'm looking for? I'm guess I'm concerned about the overhead of creating the Kernel instance.

Read the documentation: https://github.com/ninject/ninject.web.mvc/wiki/MVC3 and look at the sample project.

Related

How to resolve a DI class in a class library with .NET Core?

I understand the basics of DI in .NET Core, but I'm having trouble figuring out how to use it with multiple projects. Imagine I'm setting up a database context in the Startup class of ASP.NET Core:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<GalleryDb>();
}
I know how to access that context in an API controller:
public class AlbumController : Microsoft.AspNetCore.Mvc.Controller
{
private GalleryDb _ctx;
public AlbumController(GalleryDb ctx)
{
_ctx = ctx;
}
}
But what does one do when there are many layers and functions between the API controller and the data access class? Eventually the code reaches my repository class, which is the one that actually requires the context. It looks like this:
public class AlbumRepository
{
private GalleryDb _ctx;
public AlbumRepository(GalleryDb ctx)
{
_ctx = ctx;
}
public void Save(AlbumEntity entity)
{
// Use _ctx to persist to DB.
}
}
I understand that I could pass the context from the API entry point all the way down, but that seems like an anti-pattern because it means passing it as a parameter through multiple classes and functions that have no interest in it.
Instead, I'd like to do something like this at the point where I invoke the repository class:
public void Save(AlbumEntity album)
{
var ctx = DependencyResolver.GetInstance<GalleryDb>();
var repo = new AlbumRepository(ctx);
repo.Save(album);
}
I believe some DI frameworks have something like this, but I'm trying to figure out how to do it with native .NET Core 2.0. Is this possible? What is the best practice? I found one thread (ASP.NET Core DependencyResolver) talk about using IServiceProvider but the implication was that this was not a desirable solution.
I'm hoping whatever the solution is, I can extend it to apply to other DI classes like ASP.NET Identity's RoleManager and SignInManager.
The key breakthrough chris-pratt helped me understand is that the only way this works is to use DI through all the layers. For example, down in the data layer I get a DB context through DI:
public class AlbumRepository
{
private GalleryDb _ctx;
public AlbumRepository(GalleryDb ctx)
{
_ctx = ctx;
}
}
In the business layer I use DI to get a reference to the data layer:
public class Album
{
private AlbumRepository _repo;
public Album(AlbumRepository repo)
{
_repo = repo;
}
}
Then, in the web layer, I use DI to get a reference to the business layer class:
[Route("api/[controller]")]
public class AlbumController : Microsoft.AspNetCore.Mvc.Controller
{
private Album _album;
public AlbumController (Album album)
{
_album = album;
}
}
By using DI through every layer, the DI system is able to construct all the necessary classes at the point where they are needed.
This requirement has a profound impact on the architecture of an application, and I now realize that my initial hope to tweak an existing, non-DI app to start using DI for the DB context is a major undertaking.
I understand that I could pass the context from the API entry point all the way down, but that seems like an anti-pattern because it means passing it as a parameter through multiple classes and functions that have no interest in it.
No, that's not an anti-pattern. That's how you should do it. However, the bit about "classes and functions that have no interest in it" makes no sense.
Simply, if you're working with something like a repository that wraps a DbContext (a horrible idea, by the way, but we'll put a pin in that), then you shouldn't ever be dealing directly with that DbContext. Instead, you should be injecting your repository into your controllers and then simply let the context be injected into that:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<GalleryDb>();
services.AddScoped<AlbumRepository>();
}
Since ASP.NET Core knows how to inject GalleryDb, and AlbumRepository takes GalleryDb as a constructor param, you simply register AlbumRepository for injection as well (using a "scoped" or request lifetime).
Now, you can inject AlbumRepository the same way you're currently injecting the context:
public class AlbumController : Microsoft.AspNetCore.Mvc.Controller
{
private AlbumRepository _repo;
public AlbumController(AlbumRepository repo)
{
_repo = repo;
}
}
Where this starts to get tricky is when you have many repositories, especially if you have controllers that need to interact with several repositories. Eventually, your code will become a rat's nest of service config and injection boilerplate. However, at that point, you should really be employing the unit of work pattern as well, encapsulating all your repositories in one class that you can inject instead. But wait, oh yeah, that's what DbContext is already. It's a unit of work encapsulating multiple repositories, or DbSets. This is why you shouldn't being using the repository pattern in conjunction with Entity Framework. It's a pointless abstraction that does nothing but add additional and unnecessary entropy to your code.
If you want to abstract DbContext, then you should use something like the service layer pattern (not to be confused with the RPC bull excrement Microsoft refers to as the "service pattern") or the CQRS (Command Query Responsibility Segregation) pattern. The repository pattern is for one thing: abstracting away raw SQL. If you don't have raw SQL, you should not be implementing that pattern.

Onion architecture : respecting dependencies in the MVC Layer of the application

I am making a website using ASP.NET MVC and an onion architecture. I have the following architecture:
Domain : Entities / Domain Interfaces
Repository : Generic repository (for now) using Entity Framework Code First Approach
Service : Generic Service that calls the Repository
MVC
Now I am trying to create a method in my controller to start testing the methods I have implemented in Repository and Service, and I am having a hard time as to what I am allowed to create in this controller. I want to test a simple Get method in the Repository, but to do that I need GenericService object and GenericRepository object in my controller. To demonstrate what I mean here's a snippet of my GenericRepository(I will skip the interfaces):
public class GenericRepository<T> : IGenericRepository<T> where T : class
{
private readonly PrincipalServerContext context;
private DbSet<T> entities;
public Repository(PrincipalServerContext context)
{
this.context = context;
entities = context.Set<T>();
}
}
Now my GenericService:
public class GenericService<T> : IGenericService<T> where T : class
{
private IRepository<T> repository;
public GenericService(IRepository<T> repository)
{
this.repository = repository;
}
public T GetEntity(long id)
{
return repository.Get(id);
}
}
And finally, my question, am I allowed to create these objects in my controller as follows (using my dbcontext called PrincipalServerContext):
public class NavigationController : Controller
{
private IGenericService<DomainModelClassHere> domainService;
private IGenericRepository<DomainModelClassHere> domainRepo;
private PrincipalServerContext context;
public ActionResult MyMethod(){
context = new PrincipalServerContext();
domainRepo = new GenericRepository<DomainModelClassHere>(context);
domainService = new GenericService<DomainModelClassHere>(domainRepo);
if(domainService.GetEntity(1)==null)
return View("UserNotFound");//Just as an example
return View();
}
}
Is this allowed? According to Jeffrey Palermo, UI can depend on Service and Domain so I don't know about the Repository. Technically I am not using methods from repository, but I do need to add a reference to the project.
If I can't then how can I create a new GenericService if I don't have a GenericRepository? Is there a better way to instantiate my objects ?
EDIT I think the answer to my question resides in Startup.cs where I can put something like service.addScoped(typeof(IGenericRepository<>),typeof(GenericRepository<>));
but I 'm not sure about this, any ideas?
I'll answer this on my own if ever someone encounters the same problem. There are configuration methods we can use to create instances of classes when needed. In the Startup.cs file you have to add ConfigureServices(IServiceCollection services) method and inside there are several methods that can be applied to services to create these instances. For example you can use:
services.AddTransient(IGenericRepository, GenericRepository)
What is the difference between services.AddTransient, service.AddScope and service.AddSingleton methods in Asp.Net Core 1? (this link explains differences between methods).
AddTransient is good in my case because it creates an instance of an object through the whole lifespan of the application, which is what I need. This means UI is dependant on the rest of the solution, because Startup.cs needs to know about the Repositories as well as the Services.
A pretty good answer can be found here :Onion Architecture : Can UI depend on Domain.

Dependency Injection with repository "Generator"

I did my research and I can’t find any specific example of what I want to do.
I successfully implement Ninject into me MVC project. Everything works perfect. However, I want to do a last step.
Until now, I have been working like this (normal DI pattern):
public class myController : Controller
{
private iMyInterface myRepository;
public myController(iMyInterface myRepository)
{
this.myRepository = myRepository;
}
public ActionResult list(){
return view(myRepository.getMyList())
}
// rest o the code ...
}
My Question is; there is a way to do something like this? (Repository “Generator”)
public class myController : Controller
{
private iMyInterface myRepository = specialClass.GetMyRepository();
public ActionResult list(){
return view(myRepository.getMyList()) }
// rest o the code ...
}
I aware I’m writing a nonsense code, but the idea is to be able to do something similar.
Any recommendation?
I don't know what specialClass is supposed to be, but this looks a lot like the Service Locator anti-pattern in action.
The first option where the repository is injected through the constructor is better, because it gives you more options, including using specialClass:
var controller = new myController(specialClass.GetMyRepository());
I don't know Ninject, but most DI Containers give you an option to map an interface to a method call that returns an instance of the interface.
I would rather take a repository "Generator" in a constructor. That would give you the same result, but with a correct injection.

EF Context Management

What is the best way to manage the context of Entity Framework when using MVC application?
I am using a Repository/Service pattern.
Edit
After looking through some of these questions: stackoverflow.com/users/587920/sam-striano, I am more confused then before. Some say use the context per repository, but wht if I want to use multiple repositories in one controller method?
And to follow good separation design, how do you use UnitOfWork in the MVC app with out making it dependent on EF? I want to be able to unit test my controllers, model, services, etc. using a mock context?
Use a Dependency Injector/Inversion of Control framework like:
Ninject
Autofac
StructureMap
Unity
Using an IoC container, you can tell it how to manage a single data context (most commonly, per request). When you set the data context to per request, the container will auto-magically give any class that needs a data context the same data context per request.
Here is a good article on setting up Ninject.
What your code will most likely end up looking like, assuming you're using a generic repository:
Ninject Module:
public class NinjectRegistrationModule : NinjectModule
{
public override void Load()
{
Bind<MyDataContext>().ToSelf().InRequestScope();
Bind(typeof(RepositoryImplementation<>)).ToSelf().InRequestScope();
}
}
Generic Repository:
public RepositoryImplementation<T> : IRepository<T> where T : class
{
MyDataContext _dataContext;
public RepositoryImplementation<T>(MyDataContext dataContext)
{
_dataContext = dataContext;
}
// bunch of methods that utilize _dataContext
}
Service Class:
public class MyServiceClass
{
IRepository<SomeEntity> _someEntityRepository;
public MyServiceClass(IRepository<SomeEntity> someEntityRepository)
{
_someEntityRepository = someEntityRepository;
}
// do stuff with _someEntityRepository = someEntityRepository;
}
Controller:
public class MyController
{
MyServiceClass _myServiceClass;
public MyController(MyServiceClass myServiceClass)
{
// Ninject will auto-magically give us a myServiceClass
// which will Ninject will inject a repository into MyServiceClass's constructor
_myServiceClass = myServiceClass;
}
public ActionResult MyAction()
{
// use _myServiceClass to do stuff
return View();
}
}
If your functionality is straight forward, then you should create a new ObjectContext in each Repository. They are cheap to instantiate.
If this creates a conflict, you can use a Unit of Work pattern as was suggested in the comment.
I would advise that you be extremely cautious when integrating an ObjectContext or DataContext with a DI container. Many do not use the appropriate scope for their life cycle by default.

Is there a good/proper way of solving the dependency injection loop problem in the ASP.NET MVC ContactsManager tutorial?

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.

Resources