Best practices for IoC in complex service layer [duplicate] - c#

This question already has answers here:
How to avoid Dependency Injection constructor madness?
(10 answers)
Closed 7 years ago.
I'm developing an MVC application, I'm using Unity for IoC. My Application basically consists of a UI layer, a services layer and a repository layer.
My typical controller is:
public class TestController : Controller
{
private ITestService testServ;
public TestController(ITestService _testServ)
{
testServ= _testServ;
}
public ActionResult Index()
{
testServ.DoSomething();
return View();
}
}
Nothing out of the ordinary, each of my controllers has a service object injected. So of my service layer objects carry out complex business rules aggregating information from many different repositories. By using IoC I'm finding my constructors look overly complex, but as the service requires access to many repositories I cannot see any way around this.
A typical class in my service layer will look like:
public class TestService : ITestService
{
private ITransactionRepository transRepo;
private IAccountRepository accountRepo;
private ISystemsRepository sysRepo;
private IScheduleRepository schRepo;
private IProfileRepository profileRepo;
public TestService(ITransactionRepository _transRepo;
IAccountRepository _accountRepo;
ISystemsRepository _sysRepo;
IScheduleRepository _schRepo;
IProfileRepository _profileRepo)
{
transRepo = _transRepo;
accountRepo = _accountRepo;
sysRepo = _sysRepo;
schRepo = _schRepo;
profileRepo = _profileRepo;
}
public DoSomething()
{
//Implement Business Logix
}
}
Several of my service layer object require 10 or more repositories. My repository sits is using Entity Framework where each repository class exposes a table in the underlying data store.
I'm looking for some advice on best practice in a situation like described.

You have created a service layer so that it acts as a facade to the underlying repositories. This approach is a good practice to provide a facade to the client with a coarse API. The clients do not have to worry about underlying repositories.
The service themselves have now a complex constructor because of the way the DI is done. The other approach is to use an abstract factory pattern at the Service layer and do a setter injection. This complexity of newing up the repositories are moved into a separate class, a factory of its own.
For example:
You may set the repositories of your test service as follows instead of a constructor
public class TestService : ITestService
{
private ITransactionRepository transRepo = DataAccess.transRepo;
private IAccountRepository accountRepo = DataAccess.accountRepo;
private ISystemsRepository sysRepo = DataAccess.sysRepo;
private IScheduleRepository schRepo = DataAccess.schRepo ;
private IProfileRepository profileRepo = DataAccess.profileRepo;
}
Below is an example of an interface for factory
public interface IRepoFactory
{
ITransactionRepository TransRepo {get;}
IAccountRepository AccountRepo {get;}
ISystemsRepository SysRepo {get;}
IScheduleRepository SchRepo {get;}
IProfileRepository ProfileRepo {get;}
}
Below is an example of a concrete factory that will new up all the repositories.
public class EfFactory : IRepoFactory
{
public ITransactionRepositry TransRepo { return new TransactionRepository();}
public IAccountRepository AccountRepo {return new AccountRepository();}
public ISystemsRepository SysRepo {return new SystemRepository();}
public IScheduleRepository SchRepo {return new SchRepository();}
public IProfileRepository ProfileRepo {return new ProfileRepository();}
}
Below is a factory method that will return the concrete factory (in your case, it would be an EF Factory)
public class RepoFactories
{
public static IRepoFactory GetFactory(string typeOfFactory)
{
return (IRepoFactory)Activator.CreateInstance(Type.GetTypetypeOfFactory)
}
}
The abstract factory with static methods to new up and return the repository objects
//Example: factoryName = MyProject.Data.EFFactory ( This can be added in your web.config or app.config)
Public static class DataAccess
{
private static readonly string DbfactoryName= ConfigurationManager.AppSettings.Get("factoryName");
private static readonly IRepoFactory factory = RepoFactories.GetFactory(DbfactoryName);
public static ITransactionRepositry transRepo
{
get {return factory.TransRepo;}
}
public static IAccountRepository accountRepo
{
get {return factory.AccountRepo;}
}
}

Here are some steps to simplify (and decrease) dependencies:
Split you service into separate services and inject them in your controller. That will decrease number of dependencies of services. The downside is that you'll need to inject more dependencies to your controllers. The next step is split controllers when they become complicated. Remember about Single Responsibility Principle.
Take a look at Bounded Context pattern: you could try to group entities that often comes together in single context and inject that context into a service instead of injecting tens of repositories:
public class TestService : ITestService
{
private readonly ITestData testData; // represents a bounded context
public TestService(ITestData testData)
{
this.testData = testData;
}
public void DoSomething()
{
this.testData.Transactions.Add(...); //It gives you access to Transactions repository
}
}

Related

Dependency Injection: how do I integrate values received from method parameters into dependencies that I want to resolve as constructor parameters?

Please bear with me - this is a complicated question, and I've simplified it as much as I am able. (I'm using ASP.NET web API and AutoFac and omitted a bunch of configuration for brevity.)
My goal is to maximize the extent to which dependency-injection is handled by a DI framework, in a situation where not all dependencies of some objects can be known until runtime.
Our players are:
a CONTROLLER class that accepts web requests, the entry point to the app - the input includes repoName
a REPOSITORY RESOLVER class, a factory that resolves a repoName into a specific REPOSITORY. Here's its implementation:
public class RepositoryResolver : IRepositoryResolver
{
public IRepository Resolve(string repoName)
{
return new Repository(new Input { RepoName = repoName });
}
}
a REPOSITORY class (representing a DB or whatever). Here's its implementation:
public class Repository : IRepository
{
private readonly Input input; // proxy for connection string or other identifying information
public Repository (Input input)
{
this.input = input;
}
public string[] Get()
{
return new[] { "I", "am", "a", input.RepoName };
}
}
a BUSINESS LOGIC class that computes a result. The BUSINESS LOGIC class depends on a single repository; it knows nothing of multiple repositories or the repository resolver because it's not concerned with them. Here's its implementation:
public class BusinessLogic : IBusinessLogic
{
private readonly IRepository repository;
public BusinessLogic(IRepository repository)
{
this.repository = repository;
}
public string[] Compute()
{
return repository.Get();
}
}
Procedurally, what I'm trying to accomplish (in this stripped-down toy example) is very straightforward. Here's an example implementation of the controller:
Proposed Answer #1 - Pure DI (no container)
public class PureDIController : ApiController
{
public ProceduralValuesController() { }
public IEnumerable<string> Get(string repoName)
{
IRepositoryResolver repoSource = new RepositoryResolver();
IRepository repo = repoSource.Resolve(repoName);
IBusinessLogic businessLogic = new BusinessLogic(repo);
return businessLogic.Compute();
}
}
...and this works, but obviously I'm not using a DI container here. When using pure DI like this, changes to one player tend to have ripple effects beyond its immediate collaborators and potentially through many layers (not represented here); I feel like moving this composition logic into a DI container will reduce a lot of that type of refactoring. That's the value proposition of this question.
However, when I try to rewrite this class using dependency-injection, I encounter a problem: the BUSINESS LOGIC depends on the REPOSITORY, so it cannot be resolved by a pre-created DI container. Hence, I cannot resolve the hand-waving comment here:
public class DIValuesController : ApiController
{
private readonly IRepositoryResolver repoSource;
private readonly IBusinessLogic businessLogic;
public DIValuesController(
IRepositoryResolver repoSource,
IBusinessLogic businessLogic)
{
this.repoSource = repoSource;
this.businessLogic = businessLogic;
}
public IEnumerable<string> Get(string repoName)
{
var repo = repoSource.Resolve(repoName);
/* ...handwaving to integrate repo into businessLogic... */
return businessLogic.Compute();
}
}
...because IBusinessLogic cannot be resolved at the time the controller is instantiated.
I've developed several possible solutions, and I will add them as potential answers. However, I don't like any of them, hence the post. ¯_(ツ)_/¯ Please surprise me with something I haven't thought of yet!
Yet another possibility - pass IBusinessLogic to Controller not as an instance, but as a factory (i.e. Func<string, IBusinessLogic>) and in Methode Compute Fall factory with repoName.
See, for example:
https://autofaccn.readthedocs.io/en/latest/advanced/delegate-factories.html
Answer #2 - Pass parameters as necessary
This solution abandons the original premise that we can fruitfully convert a method parameter into a constructor parameter. Instead, it assumes that the repoName (or some equivalent differentiator) will need to be passed into any function that requires that information. Here's one possible example implementation of the controller (note that BusinessLogic now requires an additional parameter):
public class ParameterPassingController : ApiController
{
private readonly IBusinessLogic businessLogic;
public ParameterPassingController(
IBusinessLogic businessLogic)
{
this.businessLogic = businessLogic;
}
public IEnumerable<string> Get(string repoName)
{
return businessLogic.Compute(repoName);
}
}
And here's the new implementation of BusinessLogic:
public class BusinessLogic : IBusinessLogic
{
private readonly IRepositoryResolver repositoryResolver;
public BusinessLogic(IRepository repositoryResolver)
{
this.repositoryResolver = repositoryResolver;
}
public string[] Compute(string repoName)
{
var repo = repositoryResolver.Resolve(repoName);
return repo.Get();
}
}
This solution feels very awkward because it modifies the BusinessLogic class to depend on a less direct object than it did before. A class's dependencies should be determined by the class, not by the needs of the caller. The BusinessLogic class was better the way it was before, and any solution that causes us to make it more complicated is probably not a good one.
Answer #3 - Introduce additional resolvers
This solution adds a BUSINESS LOGIC RESOLVER, using the same pattern as the REPOSITORY RESOLVER. (Factory pattern?)
public class BusinessLogicResolverController : ApiController
{
private readonly IRepositoryResolver repoSource;
private readonly IBusinessLogicResolver businessLogicSource;
public BusinessLogicResolverController(
IRepositoryResolver repoSource,
IBusinessLogicResolver businessLogicSource)
{
this.repoSource = repoSource;
this.businessLogicSource = businessLogicSource;
}
public IEnumerable<string> Get(string repoName)
{
var repo = repoSource.Resolve(repoName);
var businessLogic = businessLogicSource.Resolve(repo);
return businessLogic.Compute();
}
}
The thing I don't like about this is that if there are many classes that depend on a single IRepository (and in my non-trivial example, there are many), I need to create a Resolver for each of them. That also complicates other things that DI containers can help with like decorator application and stuff.
Answer #4 - Introduce temporal coupling
This solution replaces the registered implementation of IRepository with a class that also implements IRepositoryManager, allowing it to be pointed at the appropriate repo at runtime. Here's what the controller looks like now:
public class TemporallyCoupledController : ApiController
{
private readonly IRepositoryManager repoManager;
private readonly IBusinessLogic businessLogic;
public TemporallyCoupledController(
IRepositoryManager repoManager,
IBusinessLogic businessLogic)
{
this.repoManager = repoManager;
this.businessLogic = businessLogic;
}
public IEnumerable<string> Get(string repoName)
{
repoManager.Set(repoName);
return businessLogic.Compute();
}
}
...and here's the implementation of IRepositoryManager:
public class RepositoryManager : IRepositoryManager, IRepository
{
private readonly IRepositoryResolver resolver;
private IRepository repo = null;
public RepositoryManager(IRepositoryResolver resolver)
{
this.resolver = resolver;
}
void IRepositoryManager.Set(string repoName)
{
this.repo = resolver.Resolve(repoName);
}
string[] IRepository.Get()
{
if (repo == null)
throw new InvalidOperationException($"{nameof(IRepositoryManager.Set)} must be called first.");
else
return repo.Get();
}
}
This solution certainly allows the controller to stay small, but in my experience, temporal coupling almost always hurts more than it helps. Also, it's unclear that these two lines in the controller have anything to do with each other:
repoManager.Set(repoName);
return businessLogic.Compute();
...but obviously they do. So this is a pretty bad solution.
Answer #5 - Inject the parameter-based dependency inside the controller
This solution makes the controller part of the composition root, rather than having it be resolved by dependency injection. (The line where the built container is retrieved could be done in other ways, but that's not the important part - the main idea is that we need to access its BeginLifetimeScope method directly after we have the input parameters.)
public class SelfAwareDIController : ApiController
{
public SelfAwareDIController() { }
public IEnumerable<string> Get(string repoName)
{
var container = (AutofacWebApiDependencyResolver)GlobalConfiguration.Configuration.DependencyResolver;
using (var scope = container.Container.BeginLifetimeScope(builder =>
builder.RegisterInstance(new Input { RepoName = repoName }).AsSelf()))
{
var businessLogic = scope.Resolve<IBusinessLogic>();
return businessLogic.Compute();
}
}
}
This solution avoids temporal coupling (since businessLogic cannot exist outside the lifetime scope where it can be resolved). It also allows us to remove the REPOSITORY RESOLVER; I was already uncomfortable with REPOSITORY RESOLVER because it's an expansion of the Composition Root that interferes with the DI container's centralized handling of object creation. A downside is that it moves some of the container-related code into the controller rather than keeping it all in the service configuration. (Again, in a non-trivial example there may be many controllers that need to implement similar logic.) It also prevents the controller itself from being instantiated by the DI container (which you can do with AutoFac.WebApi2 package). Still, because it restricts the knowledge of this new context to the controller (and removes the necessity of having a factory class), this is probably the least objectionable of the solutions that I've identified.

Way to dynamically get repositories without a dependency on a DI container

I have a class that returns a repository (read only) using a generic method this is to reduce the number of repository classes I need to inject into classes in my business layer. It also allows me to add and use a new repo anywhere I have this wrapper class simply by adding a repo which implements IGenericReadRepo<T> as this will be registered in unity using the line Container.RegisterType(typeof(IGenericReadRepository<>), typeof(GenericReadRepository<>), new TransientLifetimeManager());. However this has is dependent on unity being the DI container. This smells to me.
public class ReadRepositoryWrapper : IReadRepositoryWrapper
{
private IUnityContainer _unityContainer;
public ReadRepositoryWrapper(IUnityContainer container)
{
_unityContainer = container;
}
public IGenericReadRepository<T> GetReadRepository<T>() where T : class
{
return _unityContainer.Resolve<IGenericReadRepository<T>>();
}
}
Can anyone think of a way to implement the GetReadRepository<T> without a the dependency on unity while not introducing any new dependencies. Or can someone think of another way to get repositories without having bloated constructors or a dependency on my context.
You can create generic factory interfaces/classes for dynamic object creation. Many DI containers support object creation using lambda expressions.
public interface IFactory<T>
{
T Create();
}
public class Factory<T> : IFactory<T>
{
private readonly Func<T> _creator;
public Factory(Func<T> creator)
{
if(creator == null)
throw new ArgumentNullException("creator");
_creator = creator;
}
public T Create()
{
return _creator();
}
}
The generic factory interface than can be injected into the consuming classes.
public class ReadRepositoryWrapper<T> : IReadRepositoryWrapper<T> where T : class
{
private readonly IFactory<IGenericReadRepository<T>> _factory;
public ReadRepositoryWrapper(IFactory<IGenericReadRepository<T>> factory)
{
if(factory == null)
throw new ArgumentNullException("factory");
_factory = factory;
}
public IGenericReadRepository<T> GetReadRepository()
{
return _factory.Create();
}
}
Or something like that.

Proper way to use dependency injection when some arguments will be known only at runtime [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I read a bunch of questions and all docs at Ninject wiki, but I still doubt and ask questions to myself like "Am I doing it right?"
What if I need to use controller for initialization of object? And field argument will be known only at runtime?
A) So I need something like this:
public class MyClass : IMyInterface
{
private string _field;
readonly IRepository _repo;
public MyClass(string field, IRepository repo)
{
_field = field;
_repo = repo;
}
}
But how to Bind it properly? Or should I forever forget about using constructor for any reason but Constructor Dependency Injection?
B) And do it like:
public class MyClass : IMyInterface
{
private string _field;
readonly IRepository _repo;
public MyClass(IRepository repo)
{
_repo = repo;
}
public void Initialize(string field)
{
_field = field;
}
}
I think it isn't ok to call anytime when I need object this Initialize function or I'm wrong?
According to this answers Can't combine Factory / DI and Dependency Inject (DI) "friendly" library and Is there a pattern for initializing objects created via a DI container
Use Abstract Factory if you need a short-lived object
Dependencies injected with Constructor Injection tend to be long-lived, but sometimes you need a short-lived object, or to construct the dependency based on a value known only at run-time.
C) I should do it like:
public interface IMyInterface { }
public interface IMyFactory
{
MyClass Create(string field);
}
public class MyFactory : IMyFactory
{
private readonly IRepository _repo;
public MyFactory (IRepository repo)
{
_repo = repo;
}
public MyClass Create(string field)
{
return new MyClass(_repo, field);
}
}
public class MyClass : IMyInterface
{
private string _field;
readonly IRepository _repo;
public MyClass(IRepository repo, string field)
{
_repo = repo;
_field = field;
}
}
And if I need MyClass from another class I gonna use it like
public class OtherClass
{
private IMyInterface _myClass;
public OtherClass(IMyFactory factory)
{
_myClass = factory.Create("Something");
}
}
Isn't it too bulky?
And my question is: What I have to use A, B or C case? And why? Or maybe something else?
What if I need to use controller for initialization of object? And field argument will be known only at runtime?
As explained here, your application components should not require runtime data during initialization. Instead you should either:
pass runtime data through method calls of the API or
retrieve runtime data from specific abstractions that allow resolving runtime data.
Contrary to popular belief, abstract factories are hardly ever the right solution to this problem, because:
Instead of lowering complexity for the consumer, a factory actually increases complexity, because instead of having just a dependency on the service abstraction IService, the consumer now requires a dependency on both IService and the Abstract Factory IServiceFactory. [...] the increase in complexity can be felt instantly when unit testing such classes. Not only does this force us to test the interaction the consumer has with the service, we have to test the interaction with the factory as well.
For a detailed discussion, read this article.
The answer is, as always, it depends. Without the context it will be hard to advise.
However, there is one thing I would hesitate to do - configure to inject "pure" string to components. The string can mean thousands of things and it may be very hard to support that design later. Of course you can define that a string injected to XController will be a connection string to SQL and when injected to YController will be an authorization token, but I doubt it will be readable and easy to maintain.
That's being said I would choose option C or following approach:
public class DescriptiveMeaningOfAClass
{
public string Value { get; set; }
}
public class MyClass : IMyInterface
{
private string _field;
readonly IRepository _repo;
public MyClass(DescriptiveMeaningOfAClass something, IRepository repo)
{
_field = something.Value;
_repo = repo;
}
}
Personnaly I would mix A) and C) by using ChildKernel instead of referencing directly the constructor. https://github.com/ninject/Ninject.Extensions.ChildKernel
In your factory:
var parentKernel = new StandardKernel();
var childKernel1 = new ChildKernel(parentKernel);
childKernel1.Bind<string>().ToConstant("MyRuntimeValue");
var myClass = childKernel1.Get<MyClass>();
I didn't test it but it should work.

Dependency Injection and project references [duplicate]

This question already has answers here:
Ioc/DI - Why do I have to reference all layers/assemblies in application's entry point?
(4 answers)
Closed 6 years ago.
I am trying to learn about DI, to have a better understanding of IoC, and the other benefits.
Pre DI, I have a project that has a UI project (MVC), a BusinessLogic project and a DataAccess project. I also have a SharedLib project. All projects have a reference to SharedLib. UI has a reference to BusinessLogic, and BusinessLogic has a reference to DataAccess.
I want to add the Interfaces now. So I go to my DataAccess, and add an Interface for each class, and populat them with their methods. I do the same for the business logic layer.
But in order to inject the DataAccess class, which I instantiate in the BusinessLogic class in the UI project, I need a reference to my Data project, because the UI project (correctly, I think) has no idea what an 'IDataAccess' interface is. The only fix I can see is to add a project reference in my UI to my DA project - which seems wrong.
And if I try add Unity as my container (One day in the future, once i work out how that all works), and want to initialise my Interface/Class relationships in the UI project - same issue.
Maybe the interfaces must go in some shared project? Or one project up? How should this be handled?
If you don't want the references between projects you could look into factories/abstract factories.
Your UI knows about your business layer, so you want to define a factory in your business layer which knows how to use the data layer. Then you handle all your DI in your composition root (the UI project in this example).
A simple example below using a console app as the UI, sticking to the references you stated in your question
Data layer
public interface IDataAccess
{
string GetData();
}
public class XmlDataAccess : IDataAccess
{
public string GetData()
{
return "some data";
}
}
Business layer
public interface IDataAccessFactory
{
IDataAccess GetDataAccess();
}
public class XmlDataAccessFactory : IDataAccessFactory
{
public IDataAccess GetDataAccess()
{
return new XmlDataAccess();
}
}
public class BusinessLogic
{
IDataAccessFactory dataAccessFactory;
public BusinessLogic(IDataAccessFactory dataAccessFactory)
{
this.dataAccessFactory = dataAccessFactory;
}
public void DoSomethingWithData()
{
IDataAccess dataAccess = dataAccessFactory.GetDataAccess();
Console.WriteLine(dataAccess.GetData());
}
public string GetSomeData()
{
IDataAccess dataAccess = dataAccessFactory.GetDataAccess();
return dataAccess.GetData();
}
}
UI
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IDataAccessFactory, XmlDataAccessFactory>();
var logic = container.Resolve<BusinessLogic>();
logic.DoSomethingWithData();
string useDataInUI = logic.GetSomeData();
Console.WriteLine("UI " + useDataInUI);
Console.ReadKey();
}
It's a contrived example so it looks like abstraction for nothing, but with a real world example it would make more sense.
e.g. you might have a bunch of different data access classes in your data layer database, xml files, etc. so you might define a factory for each in your business layer.
Using abstract factories
The factory could contain a lot more logic about the nitty gritty of the data layer, or as an abstract factory provide a set of individual factories to the business logic layer.
Business layer
You might instead have an abstract factory in the business layer such as
public interface IPlatformFactory
{
IDataAccessFactory GetDataAccessFactory();
IPricingFactory GetPricingFactory(); // might be in the business project, or another project referenced by it
}
with a concrete factory
public class WebPlatformFactory : IPlatformFactory
{
IDataAccessFactory GetDataAccessFactory()
{
return new XmlDataAccessFactory();
}
IPricingFactory GetPricingFactory()
{
return new WebPricingFactory(); // not shown in the example
}
}
(You might have additional concrete factories such as RetailPlatformFactory, etc.)
Your BusinessLogic class would now look something like
public class BusinessLogic
{
IPlatformFactory platformFactory;
public BusinessLogic(IPlatformFactory platformFactory)
{
this.platformFactory = platformFactory;
}
public void DoSomethingWithData()
{
IDataAccessFactory dataAccessFactory = platformFactory.GetDataAccessFactory();
IDataAccess dataAccess = dataAccessFactory.GetDataAccess();
Console.WriteLine(dataAccess.GetData());
}
public string GetSomeData()
{
IDataAccessFactory dataAccessFactory = platformFactory.GetDataAccessFactory();
IDataAccess dataAccess = dataAccessFactory.GetDataAccess();
return dataAccess.GetData();
}
}
Data layer
Your business layer no longer needs to provide an IDataAccessFactory to your UI so you can move it into your data layer in this example. So the data layer classes would be
public interface IDataAccess
{
string GetData();
}
public class XmlDataAccess : IDataAccess
{
public string GetData()
{
return "some data";
}
}
public interface IDataAccessFactory
{
IDataAccess GetDataAccess();
}
public class XmlDataAccessFactory : IDataAccessFactory
{
public IDataAccess GetDataAccess()
{
return new XmlDataAccess();
}
}
UI
Now you'd in the UI you'd configure the container and perform similar actions as
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IPlatformFactory, WebPlatformFactory>();
var logic = container.Resolve<BusinessLogic>();
logic.DoSomethingWithData();
string useDataInUI = logic.GetSomeData();
Console.WriteLine("UI " + useDataInUI);
Console.ReadKey();
}
The UI then knows nothing about the data layer/access, it's just handing off the factory creation to the business layer, which holds the data (and pricing) references.
Some recommended reading:
Composition Root
Implementing an Abstract Factory
Compose object graphs with confidence

Injecting repository dependencies into a Unit of Work

I'm trying to employ the Repository and Unit of Work patterns in my asp.net MVC project, however I'm having difficulty figuring out how to pass Repository dependencies to the Unit of Work. The general standard structure of the Unit of Work seems to be the following:
public class UnitOfWork : IUnitOfWork
{
private ICustomerRepository _customerRepository;
public ICustomerRepository CustomerRepository
{
get
{
if (this._customerRepository == null)
{
this._customerRepository = new CustomerRepository(someContext);
}
return _customerRepository;
}
}
}
Specifically, what's confusing me is this line:
this._customerRepository = new CustomerRepository(someContext);
By defining interfaces for repositories, isn't the whole idea about being able to inject Repository dependencies into the UoW as time progresses and business needs change? If so, why does almost every implementation I see online do the above? In this implementation how are we supposed to pass a new instance of ICustomerRepository to the UoW? Surely we would need to also change code in the UoW and isn't that against the open close principle? How would I inject repositories to my UoW?
I've look around SO, and this question seems to have been asked before, but I'm still having a hard time trying to understand the proposed solution (a facade service).
There are two common ways to get an instance of your CustomerRepository.
First approach is known as constructor injection which is a simple parameter in your constructur e.g.
public class UnitOfWork : IUnitOfWork
{
public UnitOfWork(ICustomerRepository repository)
{
_customerRepository = repository;
}
private ICustomerRepository _customerRepository;
public ICustomerRepository CustomerRepository
{
get
{
if (this._customerRepository == null)
{
throw new ArgumentException("Missing repository");
}
return _customerRepository;
}
}
}
The second and more flexible way is to use an IoC Framework like Structuremap, Unity, Ninject... and so on.
Here's an example of Structuremap:
public class UnitOfWork : IUnitOfWork
{
private ICustomerRepository _customerRepository;
public ICustomerRepository CustomerRepository
{
get
{
if (this._customerRepository == null)
{
_customerRepository = ObjectFactory.GetInstance<ICustomerRepository>();
}
return _customerRepository;
}
}
}
Additionaly you need a configuraiton class to tell Structuremap which class to instantiate which could simply look like this:
public static class RepositoryRegistry
{
internal static void DefaultConfiguration(Registry registry)
{
registry.For<ICustomerRepository>().Use<CustomerRepository>();
}
}

Categories

Resources