Injecting repository dependencies into a Unit of Work - c#

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>();
}
}

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.

How to deal with an IDisposable repository with Unity?

I have a job in which I have an IDisposable DbContext. I would like to unit test this job without hitting in a database. What options do i have to do this?
Im using the default Fakes assembly' of microsoft.
My job:
public void Work()
{
do
{
//code here
using (var repository = new Repository<User>())
{
repository.Save(user);
}
} while (true);
}
I'm trying to test and in this part of the test it fails because it actually creates a new instance of the Repository class.
My test Method:
using (ShimsContext.Create())
{
Data.Repository.Fakes.ShimRepository<Domain.Fakes.ShimUser>.Constructor = (a) => { };
Data.Repository.Fakes.ShimRepository<Domain.Fakes.ShimUser>.AllInstances.SaveT0 = (a, b) =>
{
};
var service = GetService();
service.Work(); //Throws exception
}
How can I fake this Save method?
You've violated DIP here, making unit testing your service far more difficult than it should be. You should also avoid generic repositories and favour role interfaces.
Instead, inject an abstraction into your service of your repository, e.g. IUsersRepository which defines your Save method. Then in your unit test of the service you can simply use a stub implementation of IUsersRepository.
Fakes tend to reveal that your code is not properly following the D in SOLID since you are creating dependencies inside your class instead of passing them in.
A much better pattern would to create an ISaveRepository interface that in turn implements IDisposable with an exposed Save() method. You should then inject an instance of your repository into your class. This will allow you to satisfy the using statement testing, as well as implement a mock that defines a .Save() method that does not hit the database.
public class Test
{
private readonly ISaveRepository _userRepository;
public Test(ISaveRepository userRepository)
{
_userRepository = userRepository;
}
public void Work()
{
using (_userRepository)
{
var cont = true;
do
{
_userRepository.Save(new User());
cont = false;
} while (cont);
}
}
}
public interface ISaveRepository : IDisposable
{
void Save<T>(T model);
}
public class Repository<T> : ISaveRepository
{
public void Dispose() { }
public void Save<TT>(TT model) {}
}
public class User {}

Best practices for IoC in complex service layer [duplicate]

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
}
}

Filter constructor injection using Ninject

I am trying to find a way to use Ninject to inject constructor dependencies into filters. I am finding many articles describing property injection which is now advised against, but the remainder of articles involve complex setups with factories, locators, global wrappers or stub attributes.
With MVC allowing you to override almost any part of it's operation I would have thought it would be simply a case of creating your own filter provider in a similar fashion to how you create your own dependency resolver.
What is the now correct way to allow injection, or does it become easier if you use certain types of filters vs others?
public class UserValidationAttribute : ActionFilterAttribute
{
private IRepository repository;
public UserValidationAttribute(IRepository repository)
{
this.repository = repository;
}
}
There is a way to use constructor injection.
First you replace your attribute with an 'empty' one which you will just use as a marker
public class UserValidationAttribute : Attribute { }
Then you create a filter class as an IActionFilter.
public class UserValidationFilter : IActionFilter
{
private readonly IRepository repository;
public UserValidationFilter(IRepository repository)
{
this.repository = repository;
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
//do something
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
//do something
}
}
Then you can register it with something like
private static void RegisterServices(IKernel kernel)
{
kernel.BindFilter<UserValidationFilter>(FilterScope.Action, 0)
.WhenActionMethodHas<UserValidationAttribute>();
}
If your attribute itself has constructor parameters, you can pass them in like
kernel.BindFilter<UserValidationFilter>(FilterScope.Action, 0)
.WhenActionMethodHas<UserValidationAttribute>();
.WithConstructorArgumentFromActionAttribute<UserValidationAttribute>("myParameter", attr => attr.MyParameter);
The BindFilter syntax is part of Ninject.Web.Mvc.FilterBindingSyntax.
Assuming that the attribute is to be a part of the metadata, which means that it should be instantiated at the compile time, it is not possible to have a repository injected into an attribute by any ioc container. Containers operate in run time.
If you want to inject dependencies to a filer, you want to use property injection instead of constructor injection.
public class UserValidationAttribute : ActionFilterAttribute
{
[Inject]
private IRepository repository { get; set; }
public UserValidationAttribute()
{
}
}
https://stackoverflow.com/a/7192754/296861

Categories

Resources