I have 'standard' MVC application in next structure: UI (MVC), Business logic and data access using FluentNHibernate. I've done all steps for registering in castle container my components as described in castle documentation, used FluentRegistration API. So, all components were registered using WIndsor Installers like this:
container.Register(Classes.FromThisAssembly()
.BasedOn(typeof(IHandlerBase<>))
.WithService.AllInterfaces()
.LifestyleTransient());
In this code IHandlerBase - generic interface from which derives all my nested classes in business logic. Data access registered in same way and when I start my app all my components and services registered in container. All dependencies in MVC project relatively to BL resolved, but when I need my dependencies in business logic relatively to DataAccess they didn't. Stub example of my modules:
MVC
public ILogger Logger { get; set; } // Resolved, not null
public IHandlerBase<FooRerquest> FooHandler<FooRequest> { get; set; } // Resolved, not null
// Call Foohandler method
FooHandler.MethodName() { ... } // Here works fine
BusinessLogic
public ILogger Logger { get; set; } // Unresolved, null
public IRepository <FooCommand> FooRepository<FooCommand> { get; set; } // Unresolved, null
// Call FooRepository method
FooRepository.MethodName() { ... } // Doesn't work, catch ArgumentNullException
ILogger is a Castle NLog Facility
What and where I do in wrong way?
Thanks, Andrew
It works in UI because Controllers are created via custom ControllerFactory which uses container usually.
If instances of your business logic classes are resolved as part of MVC classes, they should be resolved. If simply constructors are used to create instances of your business logic classes then they know nothing about IoC and all references can't be resolved.
I suggest you use constructor injection since it makes Dependency Injection more visible.
Related
I have a C# & ASP.NET MVC project using a Repository pattern with Ninject.
The current controller has all the injections for my data repositories that I guess I have to keep away of the System.Web assembly, because the data repository should only know about database and nothing else.
After reviewing my code I see that I have a dependency on AppStateProvider:
public class AppStateProvider : IAppStateProvider
{
public Profile AppState
{
get
{
Profile appState = null;
if (HttpContext.Current != null && HttpContext.Current.Session["appstate"] != null)
{
appState = (Profile )HttpContext.Current.Session["appstate"];
}
return appState;
}
}
}
This dependency is registered in my NinjectWebCommon.cs:
kernel.Bind(typeof(IAppStateProvider)).To(typeof(Helpers.AppStateProvider));
The concrete class AppStateProvider lives inside my Web project in a Helpers folder.
Now, on my data project I have the following repository that injects the dependency.
public class EmployeeRepository : IEmployeeRepository
{
ILogManager _logManager = null;
private readonly Profile _appState;
public EmployeeRepository (IAppStateProvider appStateProvider, ILogManager logManager)
{
_appState = appStateProvider.AppState;
_logManager = logManager;
}
// some methods here!!
}
So, I guess I'm doing the correct way because Data Repository still doesn't know anything about the application context (HttpContext) and If I reference the same Data Repository from a Windows Service project then my concrete class that will be injected instead of calling HttpContext to get the session might call database or other place to get the Profile object property. Am I correct?
Is there a way that instead of having this extra dependency AppStateProvider I can pass to the dependencies from my controller to the Profile object without passing it to each method as a parameter, like passing it as a property object maybe?
The shown design already separates concerns via abstractions.
The composition root of the windows service project would just need to register the desired concrete implementation.
For example
//At the Composition Root of Windows Service
//...
windowsServiceKernel
.Bind(typeof(IAppStateProvider))
.To(typeof(WindowsServiceAppStateProvider));
//...
Where the concrete WindowsServiceAppStateProvider implementation lives inside the windows service project.
The data repository already explicitly states its required dependencies via constructor injection.
Nothing else really to be changed here.
It has been well documented, how to inject dependencies into services.
Question: But is it (already) possible in ASP.NET Core 2.0 to have the system's DI mechanism automatically inject a service into a method or into a property?
Sidenote: In PHP-Symfony this pattern is called setter injection.
Example:
Say I have a common MyBaseController class for all controllers in my project and I want a service (e.g. the UserManager service) to be injected into MyBaseController that can be later accessed in all child controllers. I could use constructor injection to inject the service in the child class and pass it via base(userManager) to the parent. But having to perform this in all child constructors of all controllers is pretty tedious.
So I would like to have a setter in MyBaseController like this:
public abstract class MyBaseController : Controller
{
public UserManager<User> userManager { get; set; }
// system should auto inject UserManager here
public void setUserManager(UserManager<User> userManager) {
this.userManager = userManager;
}
}
...so I don't have to do the following in every child constructor just to pass the dependency to the parent:
public class UsersController : MyBaseController
{
public ChildController(UserManager<User> userManager) : base(userManager) {}
Update: The answer given here is what I want to achieve, however the question was asked for ASP.NET Core 1.0, I'm interested in whether any solutions have been added in ASP.NET Core 2.0.
In general it is good advice to avoid non constructor DI as it is considered a bit of an anti pattern, there is a good discussion about it in this related question.
With the default Microsoft.Extensions.DependencyInjection container in aspnet core, the answer is no, but you could swap to something more powerfull like autofac (which has property injection) if you are sure you really need this feature.
You can perform setter injection with the built-in DI container (Microsoft.Extensions.DependencyInjection) using Quickwire. Unlike Autofac, this is not a new DI container, it just extends the default one.
To make it work:
Add this to ConfigureServices
public void ConfigureServices(IServiceCollection services)
{
// Activate controllers using the dependency injection container
services.AddControllers().AddControllersAsServices();
services.ScanCurrentAssembly();
// ...
// Register your other services
}
By default, ASP.NET Core will activate controllers by instantiating them directly without going through the DI container. Fortunately, this behaviour can easily be overridden to force ASP.NET Core to resolve controllers using dependency injection. This is what services.AddControllers().AddControllersAsServices() does.
ScanCurrentAssembly is necessary to get Quickwire to search for services declared in your assembly and register them (which will include your controllers).
Decorate your child controller with [RegisterService]
[RegisterService(ServiceLifetime.Transient)]
public class ChildController : MyBaseController
{
// ...
}
This will make your ChildController discoverable when ScanCurrentAssembly is called in step 1.
Decorate the setter
public abstract class MyBaseController : Controller
{
[InjectService]
public UserManager<User> UserManager { get; private set; }
}
Now the UserManager property in your child controller will be automatically set from the dependency injection container.
You have two kind of DI
Mandatory, it's injection needed for object initialization then it's injection setted in constructor.
Optional, it's injection needed for action.
If DI is doing well, u can have unit test without injection system, if all injections are in ctor then you'll break every unit test, every time for nothing.
So all injections in ctor break open/close principle.
One more point is DI is for interface implementation or module public part, object under this implementation are initialized manually.
So setter is not bad because there are hidden by interface.
Say I've a MVC Core Controller like this:
public class SomeController
{
public SomeController(IConfiguration appConfig, Func<string> someDelegate)
{
}
}
Also, I'm using AutoFac to resolve injections. Object injections are working flawlessly while adding a delegate injection produces an ASP.NET Core exception which tells that Func<string> can't be injected because there's no component to inject with such type.
When I try to manually resolve SomeController using AutoFac I get the desired behavior.
Is there any way to support this scenario without using AutoFac to resolve controllers?
Controllers are not resolved via DI by default, they are constructed in the DefaultControllerFactory or so.
Update
Microsoft.Extensions.DependencyInjection doesn't support named components, discovery, auto registrations, decorators etc.
It's meant to be simple out of the box IoC and provide the base for DI for basic applications and offer easy way for 3rd party IoC containers (with advanced features such as auto discovery, decorators etc.) to be integrated (basically all they need is process the information in IServiceCollection and return their own implementation of IServiceProvider from Configure method).
Tag helpers, controllers and view components are different in this aspect as they have their own activators (the default one use activation utilities, which at some point further down the pipeline use the service provider). For that reasons AddControllersAsServices exists, because it replaces DefaultControllerActivator (which uses ActivationUtilities, see DefaultControllerActivator.cs) with ServiceBasedActivator (which uses IServiceProvider, see ServiceBasedControllerActivator).
Also see this related answer for details on how to resolve controllers, tag helpers and view components via DI.
var builder = services
.AddMvc()
.AddControllersAsServices() // this one for your case
.AddViewComponentsAsServices()
.AddTagHelpersAsServices();
I was just run into this issue myself so I thought I would share for future reference as I had one case where I wanted to resolve a delegate but including an additional library seemed like overkill.
Given the following defintions:
public interface ISomething { /*...*/ };
public interface ISomeService { /*...*/ }
public class SomeService : ISomeService { /*...*/ }
public class Something
{
public Something(ISomeService service, string key) { /*...*/ }
}
// I prefer using a delegate for readability but you
// don't have to use one
public delegate ISomething CreateSomething(string key);
The delegate can be registered like this:
var builder = services
.AddSingleton<ISomeService, SomeService>()
.AddTrasient<CreateSomething>(provider => key => new Something(provider.GetRequiredService<ISomeService>(), key));
I understand DI and IoC but I can't seem to understand how to implement it in a nTier application. This is a simple MVC application I'm trying to build with one domain object.
Layers: DAL and UI will reference the BLL Layer.
DAL<--BLL-->UI
DAL will contain EntityFramework, SQLBlogRepository, Blog.cs and Mapper
BAL will contain IBlogRepository, Domain object: Blog.cs
UI will implement Constructor DI of IBlogRepository
This is where I'm stuck. How can I used Ninject so the constructor know to used SqlBlogRepository implementation? I also ran into a few examples that uses "Composition Root" which add more confusion. Then there are example that uses Repository Pattern. The bottom line is, I'm trying implement a nTier MVC application that is loosely couple and used IoC/Dependency Injection. Please help me map out how I can make a call from the UI layer and have the DAL layer return data via BLL layer while all three layer are loosely coupled.
I am assuming you do not have a ninject configuration file created. So here is how we did it where I am at.
To explain what I am doing. You need to have your concrete class implement whatever Interface you want to use.
In the ninject config file you need to bind your Interfaces to your concrete classes. Then you can call ninject to get your interfaces and it will return the concrete class that you want.
If you want to use this in an N- Tier development environment.
DAL <- >BL <->UI
We stuck the ninject configuration in the BL. Since the Bl is the only layer that References the DAL. We exposed the DAL interfaces/concrete classes to the BL via references. Then in the BL we added the Ninject Configuration.
Once that was done in the UI we were able to access all of the Business objects.
ninject starter tutorial
DAL
public interface IRepository
{
//does some things
}
public SQLBlogRepository : IRepository
{
//implements IRepository
}
BL
NINJECT CONFIGURATION FILE
public Foo : IFOO
{
public Foo(IRepository steve){}
}
public interface IFOO
{
}
public class NinjectConfig : NinjectModule
{
public override void Load()
{
Bind<IRepository>.To<SQLBlogRepository>();
Bind<IFOO>.To<Foo>();
}
}
then you use it like so.
var repo = new StandardKernel(new NinjectConfig()).Get<IRepository>();
var fooManager = new StandardKernel(new NinjectConfig()).Get<IFOO>();
The var fooManager, through the power of ninject will autoInstantiate your repo. So you do not need to create it yourself. The config file will handle all the dependancies in the constructor. So you never need to know what constructor creations you need to do. And you can also change the creations in one spot and propagate it out automagically through your code.
In your sample the UI (Mvc Project) is your Composition Root and you can config your dependency in it (with any ioc container like ninject). Your mvc project must have a reference to BLL and DAL layer and you must make a mapping like #gh9 answer in your mvc project.
In your controller you have
public class HomeController : Controller
{
private readonly IFOO _fooBll;
public HomeController(IFOO fooBll){
_fooBll=fooBll;
}
public ActionResult Index()
{
return View();
}
}
and you must have a controller factory to resolve your controller dependency like :
public class NinjectControllerFactory : DefaultControllerFactory
{
private IKernel ninjectKernel;
public NinjectControllerFactory()
{
ninjectKernel = new StandardKernel();
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
return controllerType == null
? null
: (IController) ninjectKernel.Get(controllerType);
}
}
I've taken this approach to injecting a custom resource provider in my ASP.NET MVC application, but I'm having some problems with object lifetime management.
I'm using Castle Windsor, so I have the following implementation of the factory:
public class DefaultResourceProviderFactory : ResourceProviderFactory
{
public override IResourceProvider CreateGlobalResourceProvider(string classKey)
{
// IoC is a static helper class that gives me static access to the
// container. IoC.Resolve<T>(args...) simply calls container.Resolve<T>(args...).
return IoC.Resolve<IResourceProvider>(new { resourceType = "Global" });
}
public override IResourceProvider CreateLocalResourceProvider(string virtualPath)
{
// resourceType
return IoC.Resolve<IResourceProvider>(new { ResourceType = virtualPath });
}
}
However, the IResourceProvider I have registered in the container doesn't seem to have its lifetime managed correctly. It has some other dependencies of its own, some of which have somewhat complicated lifestyles (per web request or per transaction), so I've registered the IResourceProvider as transient to ensure that its dependencies are always valid. But the MVC framework is stepping on my toes, keeping a reference to the IResourceProvider across web requests, which causes ObjectDisposedExceptions when its dependencies have been invalidated on the next request.
What I'd like to do, is to make the MVC framework use the factory every time it needs an instance of my IResourceProvider, and - if possible - also to invoke IoC.Release(provider) or something similar when it's done with it.
How do I micro-manage the lifestyle of the custom IResourceProvider in a way that the MVC framework will respect?
After searching around for various ways to control the lifetime of the IResourceProvider itself, I decided that it was better to refactor my implementation to utilize the Typed Factory Facility.
My IResourceProvider implementation formerly looked something like this:
public class CachedResourceProvider : IResourceProvider {
CachedResourceProvider(IResourceRecordRepository repo) { /* ... */ }
// other members...
}
Now, I changed it to this instead:
public class CachedResourceProvider : IResourceProvider {
CachedResourceProvider(IResourceRecordRepositoryFactory repo) { /* ... */ }
// other members...
}
The factory interface is a new one, defined as
public interface IResourceRecordRepositoryFactory {
IResourceRecord NewInstance();
void Release(IResourceRecord instance);
}
and every usage of the private _repo instance in the CachedResourceProvider was refactored to three statements: get a repo instance from the factory, use the repo instance to fetch/save something, release the instance through the factory.
I registered them like this:
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IResourceRecordRepositoryFactory>().AsFactory());
Now, even though MVC is keeping a reference to my resource provider across web requests, the services it uses are re-fetched from the Windsor container each time they're used, so the container is in full control of their lifetime.