Dependency Injection / Constructor Injection Help - c#

I have the following classes / interfaces:
public interface IProjectRepository
{
IQueryably<Project> GetProjects();
}
// Depends on my EF Context
public ProjectRepository : IProjectRepository
{
private MyDbEntities context;
public ProjectRepository(MyDbEntities context)
{
this.context = context;
}
public IQueryable<Project> GetProjects()
{
return context.Projects;
}
}
My controller:
// Depends on IProjectRepository
public class ProjectsController : Controller
{
private IProjectRepository projectRepository;
public ProjectsController(IProjectRepository projectRepository)
{
this.projectRepository = projectRepository;
}
public ActionResult Index()
{
return View(projectRepository.GetProjects());
}
}
I need to set up my dependency injection so that it passes in ProjectRepository into my Controller AND it needs to pass in my Entity Framework context into the Project Repository. I need to Entity Context to be HTTP Request scoped.
I'm not sure where I am supposed to put all the mapping code to make the dependency injection work. I also don't understand how MVC will work without the default constructor.
Can someone help me put all the pieces together? I am using StructureMap but I could easily switch to something else because I have no idea what I'm doing.

If you are using MVC 3, to do things properly, you should make use of the built in dependency resolution bits. I would highly recommend you read through the series of blog posts from Brad Wilson (member of the ASP.NET MVC team).
As far as a StructureMap specific implementation, I found the following blog posts helpful.
StructureMap and ASP.NET MVC 3 – Getting Started
StructureMap, Model Binders and Dependency Injection in ASP.NET MVC 3
StructureMap, Action Filters and Dependency Injection in ASP.NET MVC 3
StructureMap, Global Action Filters and Dependency Injection in ASP.NET MVC 3
Anyway, here's some code. To start with, I would suggest that you install the StructureMap-MVC3 NuGet package.
I can't remember what exactly it creates in the way of files, but here's what's basically involved.
/App_Start/StructuremapMvc.cs - This hooks into the Application_Start and sets up your container (SmIoC.Initialize()) and then sets the MVC 3 DependencyResolver to a your SmDependencyResolver
using System.Web.Mvc;
using YourAppNamespace.Website.IoC;
using StructureMap;
[assembly: WebActivator.PreApplicationStartMethod(typeof(YourAppNamespace.App_Start.StructuremapMvc), "Start")]
namespace YourAppNamespace.Website.App_Start {
public static class StructuremapMvc {
public static void Start() {
var container = SmIoC.Initialize();
DependencyResolver.SetResolver(new SmDependencyResolver(container));
}
}
}
/IoC/SmDependencyResolver.cs - this is your MVC 3 IDependencyResolver implementation. It's used in the App_Start code above.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using StructureMap;
namespace YourAppNamespace.Website.IoC
{
public class SmDependencyResolver : IDependencyResolver
{
private readonly IContainer _container;
public SmDependencyResolver(IContainer container)
{
_container = container;
}
public object GetService(Type serviceType)
{
if (serviceType == null)
{
return null;
}
try
{
return _container.GetInstance(serviceType);
}
catch
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
return _container.GetAllInstances(serviceType).Cast<object>(); ;
}
}
}
/IoC/SmIoC.cs - this is where you setup your container... also used in the App_Start code.
namespace YourAppNamespace.Website.IoC
{
public static class SmIoC
{
public static IContainer Initialize()
{
ObjectFactory.Initialize(x =>
{
x.For<IProjectRepository>().Use<ProjectRepository>();
//etc...
});
return ObjectFactory.Container;
}
}
}
Now everything is hooked up... (I think ;-) but you still have one last thing to do. Inside your Global.asax, we need to make sure you dispose of everything that is HttpContext scoped.
protected void Application_EndRequest()
{
ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
}
So you should be able to achieve dependency injection through constructor injection, which is the correct way to go about doing things.

If you are set on using StructureMap, here is a tutorial on the setup that you will probably need.
Some other dependency injection frameworks come with custom controller factories which will do that for you. Ninject (open source dependency injection), for example has an extension that you can use that contains this behaviour. See here for example. And here to the extension.
You can use also Unity IOC which is another popular dependency injection framework with which, to my knowledge, you will have to create a custom controller factory (like with structuremap) to achieve this behaviour. See here for an example.
You can also research all other dependency injection frameworks to see what support you can get with each.
EDIT:
I hope I am explaining this correctly but here is some background info.
MVC uses a controller factory that has the responsibilities of instantiating the respective controllers needed when a request is made. By default, it will initialize a controller by calling its parameterless constructor.
To create the infrastructure for the constructor parameter injection you need to create a custom factory that can resolve constructor parameters. That is where the dependency injection containers come in: essentially the DI container (if configured properly) knows how to resolve those dependency and your custom factory will leverage it to request the registered dependencies and pass the to the controller constructor.

All work pretty much the same. Historically, all have had setter injectors (set up a property that is then filled), but most have constructor injection now. In structure map, the easiest way to accomplish this is use the attribute: [StructureMap.DefaultConstructor].
Once you add the attribute, the objects you have placed in your "map" should inject without any extra work. If you can't use attributes, consider using the setter.
There is a file on the structure map site:
http://structuremap.net/structuremap/ConstructorAndSetterInjection.htm

When using StructureMap I would generally have something like this in my controller:
private static IProjectRepository GetProjectRepository()
{
var retVal = ObjectFactory.TryGetInstance<IProjectRepository>()
?? new ProjectRepository();
return retVal;
}
If the TryGetInstance returns null (because nothing was set for that type) it will default to the concrete type you specify.
Now you have a bootstrapper somewhere like this:
public static class StructureMapBootStrapper
{
public static void InitializeStructureMap()
{
ObjectFactory.Initialize(x =>
{
x.For<IProjectRepository>().Use<ProjectRepository>();
}
}
}
Now you call this bootstrapper in your Global.asax Application_Start event:
protected void Application_Start()
{
StructureMapBootStrapper.InitializeStructureMap();
}
Now in a test project, when you want to inject a mock repository you can just do this:
[TestMethod]
public void SomeControllerTest()
{
StructureMap.ObjectFactory.Inject(
typeof(IProjectRepository),
new MockProjectRepository());
// ... do some test of your controller with the mock
}

Related

Registering IUnitOfWork As service in .net core

I am going to implement repository pattern in my asp.net core mvc application , for that i am trying my hands on a simple demo application which include repository and Unit of Work concept.
My First Repository
public interface ICustomerRepository
{
bool Add();
bool Update();
bool Delete();
}
and
public class CustomerRepository:ICustomerRepository
{
public bool Add()
{
return true;
}
public bool Update()
{
return true;
}
public bool Delete()
{
return true;
}
}
Second Repository
public interface IOrderRepository
{
bool Add();
bool Update();
bool Delete();
}
and
public class OrderRepository:IOrderRepository
{
public bool Add()
{
return true;
}
public bool Update()
{
return true;
}
public bool Delete()
{
return true;
}
}
IUnit Of Work
public interface IUnitOfWork
{
IOrderRepository Order {get;}
ICustomerRepository Customer { get; }
void Save();
void Cancel();
}
and
public class UnitOfWork:IUnitOfWork
{
public UnitOfWork(IOrderRepository order, ICustomerRepository customer)
{
Order = order;
Customer = customer;
}
public IOrderRepository Order { get; }
public ICustomerRepository Customer { get; }
public void Save() { }
public void Cancel() { }
}
And in my controller ,
public class HomeController : Controller
{
IUnitOfWork UW { get; }
public HomeController(IUnitOfWork uw)
{
UW = uw;
}
public IActionResult Index()
{
UW.Customer.Add();
UW.Order.Update();
UW.Save();
return View();
}
}
I will add more code later for dapper , but at least it should work wiyhout any error , but it give me error
InvalidOperationException: Unable to resolve service for type 'CoreTS.Repository.UnitOfWork.IUnitOfWork' while attempting to activate 'CoreTS.Controllers.HomeController'.
Someone suggested me to add IUnitOfWork as service in startup.cs under ConfigureService Method, as
services.AddSingleton<IUnitOfWork, UnitOfWork>();
And After Adding this another error
InvalidOperationException: Unable to resolve service for type 'CoreTS.Repository.Order.IOrderRepository' while attempting to activate 'CoreTS.Repository.UnitOfWork.UnitOfWork'.
To make it work i had to add other two repository also in startup.cs also
services.AddSingleton<IOrderRepository, OrderRepository>();
services.AddSingleton<ICustomerRepository, CustomerRepository>();
If there going to be n number of repository than i have to add everyone of them in startup.cs (according to this code ), what is the solution for that.
So
1.] What does these errors means ?
2.] What will be the correct configuration here ?
3.] What is the way to not to add n number of repository as service here ?
Note: As a mentioned already , this is just to understand the flow of pattern , i will add code for Dapper or EF Core later in this
What does these errors means ?
These error means that you are using the services through constructor Dependency Injection but you have not registered those services to DI resolver.
What will be the correct configuration here ?
What you have done is the correct way to resolve services.
What is the way to not to add n number of repository as service here?
You can extend the IServiceCollection as follows in a separate file.
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddCustomServices(this IServiceCollection services,
IConfiguration configuration)
{
services.AddSingleton<IUnitOfWork, UnitOfWork>();
services.AddSingleton<IOrderRepository, OrderRepository>();
services.AddSingleton<ICustomerRepository, CustomerRepository>();
return services;
}
}
Then in the startup class as follows:
services.AddCustomServices(Configuration);
The constructor for HomeController takes an IUnitOfWork, so ASP.NET Core needs to know what instance to give it, that's why you specify it in ConfigureServices. But, your UnitOfWork class' constructor takes an IOrderRepository and an ICustomerRepository, and ASP.NET Core needs to know what instances of those to supply, so you have to specify those in ConfigureServices as well.
I think the configuration you've ended up at is correct, as far as it goes, but it doesn't address your next question...
There's already a problem with your pattern without the ASP.NET Core dependency injection issues. Your constructor for UnitOfWork takes 2 distinct parameters, one for each repository. If you want to have N different repositories, that constructor no longer works. Instead, maybe you need to introduce a "repository manager" class and just inject that into the constructor (add it in ConfigureServices too). Then you need to devise a relationship between UnitOfWork and RepositoryManager that allows UnitOfWork to work with any specific repository.
Well, the error message is quite meaningful. The DI container has to resolve the instance of IUnitOfWork which has two dependencies that are injected into its ctor. So DI container has to resolve these two as well.
There is no built-in functionality in asp.net-core that allows you to register all your repositories using pattern matching or something like that. You could register all dependencies one by one or use 3rd party libraries.
With Scrutor you can do something like this:
services.Scan(scan => scan
.FromAssemblyOf<OrderRepository>()
.AddClasses(classes => classes.AssignableTo<IRepository>())
.AsImplementedInterfaces()
.WithSingletonLifetime());
Note that for it to work all repositories must implement IRepository interface (which can be empty)
Conclusion:
If it's only a few dependencies I'd probably register them one by one however if you plan to add N repositories later - use 3rd party libs.
There is no service registered in the IoC container for IUnitOfWork/IOrderRepository. You solved this by registering these services using AddSingleton method.
Not sure what you mean by correct configuration, but using AddSingleton/AddTransient/AddScoped you are registering some classes as services in the IoC container. So when you inject something (for example into your HomeController), then you are using the interface mapped to some concrete implementation.
You have to register the service somehow, that is what you are doing with methods mentioned before. If you won't register it, it won't be resolved and you will get exceptions when trying to activate some other dependent services. If you want to register some services without doing it explicitely, you will have to scan the assembly and look for types that you want to register.

Property Injection with Autofac isn't working

I've been looking through examples and documentation for Autofac, and can't see to get this working.
We have a helper class, Core.Helpers.Tokens with a property set up like this:
namespace Core.Helpers
{
public static class Tokens
{
private static IConfigurationManager ConfigurationManager;
public static string GetToken()
{
var sessionTokenName = ConfigurationManager.GetAppSetting("SessionTokenName");
return (string) HttpContext.Current.Session[sessionTokenName];
}
}
}
The configuration is designed like this:
namespace Core.Config
{
public interface IConfigurationManager
{
//...
}
public class WebConfigConfigurationManager : IConfigurationManager
{
//...
}
}
In our MVC Web app (which references and uses Core.Helpers, Startup.cs I'm trying to register IConfigurationManager for property injection.
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
var builder = new ContainerBuilder();
// REGISTER CONTROLLERS SO DEPENDENCIES ARE CONSTRUCTOR INJECTED
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterModule<AutofacWebTypesModule>();
builder.RegisterFilterProvider();
builder.RegisterType<WebConfigConfigurationManager>().As<IConfigurationManager>().PropertiesAutowired();
RegisterTypes(builder);
// BUILD THE CONTAINER
var container = builder.Build();
var webConfig = container.Resolve<IConfigurationManager>();
// REPLACE THE MVC DEPENDENCY RESOLVER WITH AUTOFAC
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
// REGISTER WITH OWIN
app.UseAutofacMiddleware(container);
app.UseAutofacMvc();
}
When the web code calls GetToken, ConfigurationManager is null. What am I missing?
One error is that your Tokens.ConfigurationManager is a private field, whereas property injection works with public properties.
Also, it must be an instance property, not static. So in the end it should be
public IConfigurationManager ConfigurationManager{get;set;}
But that would mean you'd also have to inject a Tokens instance, and that would make no longer a static helper class, you'll have to do some redesign, there are some options:
If you have an IConfigurationManager instance everywhere you expect to call GetTokens from you can pass that in as an input parameter to GetTokens()
You promote this static helper to a dependency (e.g. ITokenService ? ) that will be injected to everywhere it's needed. Instead of making it static,
you can use Autofac lifetime management to make it a singleton. (Probably the best solution)
The worst solution, but the smallest change, one that works without having to give up this being a static helper class, is to make the property use the DependencyResolver instead of injection, something like:
private static IConfigurationManager ConfigurationManager{ get { return DependencyResolver.Current.GetService();} }
You are resolving IConfigurationManager, You should be resolving WebConfigConfigurationManager.
If you have 5 classes that utilize IConfigurationmanager, resolving the interface does not tell autoface which concrete class you are wanting to utilize which has this interface.

c# dependency injection error with interface

I'm trying my hand at dependency injection for my RPG written in c# and some javascript.
I'm trying to inject a service into my controller but keep getting this error:
Error activating IdownloadService No matching bindings are available, and the type is not self-bindable.
In debug mode, it fails on this line with the above error in my CharacterController class:
public IdownloadService downloadService{ get; }
Here is the relevant code:
characterDownloadService.cs
namespace OrionRPG.Character.Downloads
{
public interface IdownloadService
{
Uri CharacterDownloadUri(int charId);
}
public class characterDownloadService : IdownloadService
{
public characterDownloadService()
{}
public const String CharacterServerUrl = "http://myUrl/Characters/";
public Uri CharacterDownloadUri(int charId)
{
var characterName = Character.Name(charId);
return new Uri(CharacterServerUrl + characterName);
}
}
}
CharacterController.cs
namespace OrionRPG.Api.Downloads
{
public class CharacterController
{
public IdownloadService downloadService{ get; }
//inject the service
public CharacterController(IdownloadService downloadService)
{
DownloadService = downloadService;
}
[Route("api/characters/download/{charId}")]
public IHttpActionResult GetCharacterDownload(int charId)
{
return Redirect(DownloadService.CharacterDownloadUri(charId));
}
}
}
Generally speaking, services need to be registered to a container before injection. Different dependency injection framework might have slightly different syntax, the principles are the same.
For example, if you are using Microsoft.Extensions.DependencyInjection, you will need to Register the service: In Startup.cs (ASP.NET Core), you will see a method named ConfigureServices, and you will need to register your service like this:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(); // Some code by template
...
// This line registers the IdownloadService; when injection happens, the service provider knows to create an implementation of characterDownloadService for requested IdownloadService.
services.AddTransient<IdownloadService, characterDownloadService>();
}
For more details, check this out.
1) As I understand you are trying to use ASP.NET WebApi and it is strange that CharacterController doesn't inherit ApiController
2) You need to use Dependency Injection container which will contains all mapping between interfaces and it's implementation. I would recommend to use Autofac as it is perfectly integrated with ASP.NET MVC and WebAPI. Here is a link with docs

Injecting dependencies into AuthorizeAttribute in a class library

I've run into an interesting design issue with a class library I am writing. I have a custom implementation of the AuthorizeAttribute that I want clients to be able to use like this:
[Protected("permission_name")]
In the above code, PermissionAttribute inherits from AuthorizeAttribute and uses a local default (DefaultContext created using HttpContext).
Behind the scenes, the attribute uses a SecurityService to check users, roles and permissions against (the SecurityService itself uses a client-provided persistence service that they can wire up in the composition root of their app).
So my attributes need a reference to the SecurityService to function. Since Attribute constructors can only have compile-time constants, I cannot use constructor injection.
I don't want to force my clients to use a DI framework - they should be able to discover and wire up the necessary dependencies in their composition root without using an IoC library, if they so choose.
Here are my options:
Have the library use a singleton SecurityService.
Use property injection, which would work but
it would make the dependency seem optional, which it is not and
I don't know where I can do property injection in an MVC app on an authorize attribute.
A possible solution to 2. above is to do set an instance of SecurityService as a static property on the attribute at application startup and use a guard clause to prevent it from being set more than once, like this:
class ProtectedAttribute : ...
{
private static ISecurityService _SecurityService ;
public static ISecurityService SecurityService
{
get
{
return _SecurityService ;
}
set
{
if (_SecurityService != null)
throw new InvalidOperationException("You can only set the SecurityService once per lifetime of this app.") ;
_SecurityService = value ;
}
}
}
The SecurityService could be an abstract service facade so that it can be extended/replaced by a different implementation.
Is there a better way to solve this problem?
UPDATE: Adding some code to show how I am going to do it:
Add a public property on the attribute that returns the permission name:
public class ProtectedAttribute : ...
{
private string _Permission ;
public string Permission { get { return _Permission ; } /*...*/ }
public ProtectedAttribute(string permission) { /*...*/ }
}
Setup an authorization filter and configure dependency via Ninject (if using Ninject):
using Ninject.Web.Mvc.FilterBindingSyntax;
public class MyModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
// mySecurityService instance below can have a singleton lifetime - perfect!
this.BindFilter<MyAuthorizationFilter>(FilterScope.Action, 0)
.WhenActionMethodHas<ProtectedAttribute>()
.WithConstructorArgument("securityService", mySecurityService)
.WithConstructorArgumentFromActionAttribute<ProtectedAttribute>("permission", p => p.PermissionName) ;
}
}
Ohhh it's...beautiful sniffle
With ASP.NET MVC 3 you could use constructor injection with action filters thanks to the new IFilterProvider. This way you no longer need to decorate your controller actions with action filters. You could apply them thanks to this interface and using a marker attribute.
And if you don't wanna bother implementing it manually you could always use an existing DI framework such as Ninject which provides a fluent way to define action filter dependencies.
My applications inherit from a base Application class that exposes the IOC container.
public interface IInjectableApplication
{
IUnityContainer Container { get; }
}
Then I have a base attribute class, which is aware of this
public abstract IocAwareActionFilterAttribute : ActionFilterAttribute{
protected T ResolveItem<T>(ResultExecutedContext context)
{
var app = context.HttpContext.ApplicationInstance as IInjectableApplication;
if (app == null) { throw new NullReferenceException("Application is not IInjectable."); }
T c = (T)app.Container.Resolve(typeof(T));
if (c == null) { throw new NullReferenceException(string.Format("Could not find injected {0}.", typeof(T).FullName)); }
return c;
}
}
While this is not true Injection, since Attributes aren't constructed 'normally', this provides a similar behavior. No reason it should not be adaptable to other IOCs

dependency injection alternatives

I am looking at depency injection, I can see the benefits but I am having problems with the syntax it creates. I have this example
public class BusinessProducts
{
IDataContext _dx;
BusinessProducts(IDataContext dx)
{
_dx = dx;
}
public List<Product> GetProducts()
{
return dx.GetProducts();
}
}
The problem is that I don't want to write
BusinessProducts bp = new BusinessProducts(dataContextImplementation);
I would continue to write
BusinessProducts bp = new BusinessProducts();
because I feel the first alternative just feels unatural. I dont want to know what the BusinessProduct "depends" on to get the products, also I feel it makes my code more unreadable.
Is there any alternatives to this approach as I would like to keep my original syntax for creating objects but I would like to still be able to fake the dependencies when unit testing or is it this dependecy injection frameworks can do for me?
I am coding in c# but alternatives from other languages is welcome
I use a factory for my context and inject it, providing a suitable default if the provided factory is null. I do this for two reasons. First, I use the data context as a unit of work scoped object so I need to be able to create them when needed, not keep one around. Second, I'm primarily using DI to increase testability, with decoupling only a secondary consideration.
So my business products class would look like:
public class BusinessProducts
{
private IDataContextFactory DataContextFactory { get; set; } // my interface
public BusinessProducts() : this(null) {}
public BusinessProducts( IDataContextFactory factory )
{
this.DataContext = factory ?? new BusinessProductsDataContextFactory();
}
public void DoSomething()
{
using (DataContext dc = this.DataContextFactory().CreateDataContext())
{
...
}
}
An alternative to this would be to make the factory property publicly settable and inject an alternate factory by setting the property. Either way if you want to keep the null constructor, you'll need to provide a default.
You can create a factory. DI containers are best for wirings that happen at setup-time - not at runtime (As this looks to be a case of). Factories can be implemented in different ways, depending on how pluggable it needs to be, and how many places you need to use it.
I would usually have an empty constructor which uses a solid instance( or an instances created by IoC), amd one with DI. i.e.
public class BusinessProducts
{
IDataContext _dx;
BusinessProducts()
{
_dx = new SolidDataContext();
}
BusinessProducts(IDataContext dx)
{
_dx = dx;
}
}
This way you can use DI for overriding the default instance in unit testing testing.
Your feelings, while valid, are misplaced.
The Dependency Injection pattern is a direct application of the Inversion of Control principle.
This means that, instead of your class controlling the instances of other classes it consumes, that relationship is inverted and the dependencies are provided to it.
As such, your classes naturally expose their dependencies via constructor arguments or properties. Showing disdain for this structure says you haven't truly grokked the pattern.
There are two distinct cases here:
In production code you will never write
new BusinessProducts(dataContextImplementation)
because dependency injection will normally be creating the full object hierarchy for you. This is the "viral" nature of dependency injection patterns, they tend to take over full control of your service creation.
In unit test code you will normally be creating this yourself, but quite often you will be supplying a mock object or a stub implementation of dataContextImplementation. So normally you will be injecting an object that does not have a large number of subsequent dependencies.
http://springframework.net/ and http://structuremap.sourceforge.net/Default.htm are probably the mostly used DI frameworks for .NET based languages and will both do what you need.
Generally the framework itself will have the logic to build up the entire object tree. For example, instead of
new SomeObjectO(diContext)
you would call the framework like this:
DIFramework.GetNew<SomeObjectO>();
or
DIFramework.Get<SomeObject>();
Another interesting framework to take a look at if you would like to learn about DI and the process is Microsoft's Unity and Object Builder projects.
If you really do not like injecting this instance in the constructor, you might try to use the CommonServiceLocator with your favourite compatible .NET depedency injection framework. This would allow you to write code like this:
public class BusinessProducts
{
IDataContext _dx;
BusinessProducts()
{
_dx = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IDataContext>();
}
public List<Product> GetProducts()
{
return dx.GetProducts();
}
}
However, please beware that this is not what most people would expect when they know that you use a dependency injection framework. I think that it is much more common to use a dependency injection framework and letting it create all objects for you.
BusinessProducts bp = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<BusinessProducts>();
If you would like to avoid the dependeny injection framework path, using a factory is probably the best way to go.
There's a technique called poor man's DI that looks like this
public class BusinessProducts
{
IDataContext _dx;
BusinessProducts() : this(new DataContext()) {}
BusinessProducts(IDataContext dx)
{
_dx = dx;
}
public List<Product> GetProducts()
{
return dx.GetProducts();
}
}
This is not ideal since it ties you to the implementation but its a good stepping stone towards decoupled code. this is similar to #tvanfosson but a lot simplier.
I second the recommendation for Windsor
My code will reference Microsoft Unity but I am sure it is pretty applicable to all DI frameworks. If you're using DI correctly you never need to call new BusinessObject(new dataContext) the DI association will handle it all for you.
My example will be a little bit long since I will paste in some code I use for running a Model View Presenter website fully DI loaded by Unity. (If you want the full source check out my blog and download it from my Assembla SVN server)
Load the container (can be in code like I prefer or using configuration)
protected void Application_Start(object sender, EventArgs e)
{
Application.GetContainer()
// presenters / controllers are per request
.RegisterType<IEmployeeController, EmployeeController>(new ContextLifetimeManager<IEmployeeController>())
//Data Providers are Per session
.RegisterType<IEmployeeDataProvider, EmployeeDataProvider>(new SessionLifetimeManager<IEmployeeDataProvider>())
//Session Factory is life time
.RegisterType<INHibernateSessionManager, NHibernateSessionManager>(new ContainerControlledLifetimeManager());
}
Custom HTTP module calls Unity BuildUp Method for each page during the OnPreRequest invocation.
private static void OnPreRequestHandlerExecute(object sender, EventArgs e)
{
var handler = HttpContext.Current.Handler;
HttpContext.Current.Application.GetContainer().BuildUp(handler.GetType(), handler);
// User Controls are ready to be built up after the page initialization is complete
var page = HttpContext.Current.Handler as Page;
if (page != null)
{
page.InitComplete += OnPageInitComplete;
}
}
Page container presenter decorated with [Dependency] attribute
public partial class Employees : Page, IEmployeeView
{
private EmployeePresenter _presenter;
[Dependency]
public EmployeePresenter Presenter
{
set
{
_presenter = value;
_presenter.View = this;
}
}
}
Presenter with InjectionConstructor method
public class EmployeePresenter : Presenter<IEmployeeView>
{
private readonly IEmployeeController _controller;
[InjectionConstructor]
}
public EmployeePresenter(IEmployeeController controller)
{
_controller = controller;
}
Controller follows suit
public class EmployeeController : IEmployeeController
{
private readonly IEmployeeDataProvider _provider;
[InjectionConstructor]
public EmployeeController(IEmployeeDataProvider DataProvider)
{
_provider = DataProvider;
}
}
Same with provider
public class EmployeeController : IEmployeeController
{
private readonly IEmployeeDataProvider _provider;
[InjectionConstructor]
public EmployeeController(IEmployeeDataProvider DataProvider)
{
_provider = DataProvider;
}
}
Lastly the session manager, which contains only a regular constructor.
public class NHibernateSessionManager : INHibernateSessionManager
{
private readonly ISessionFactory _sessionFactory;
public NHibernateSessionManager()
{
_sessionFactory = GetSessionFactory();
}
}
So what happens when a page request is started the BuildUp() method is called on the page by the HttpModule. Unity then sees the Property marked with the Dependency attribute and will check it's container to see if inside it exists an EmployeePresenter object.
Since there is no such object in the container it will then try to create an EmployeePresenter. Upon inspection to create the class it sees inside the Presenter it requires a constructor that needs a IEmployeeController injected into it. Since the container actually has a manager for the controller it will see if an instance of it exists in the container which on the beginning of the page request doesn't exist, so it will go to instantiate the controller.
Unity will then see the controller requires a IEmployeeDataProvider injected into it, and it will continue on this process until it finally gets to the point where the Provider needs the session manager injected. Since the session manager has no more need for injection Unity will then create an instance of the session manager store it in the container for it's given ContainerLifeTimeManager, inject it into the Provider and store that instance, and so on down to where it finished creating a EmployeePresenter dependency for the page.
you can also look at windsor for IoC .

Categories

Resources