I want to implement Unit Of Work design pattern in my project and from this article the dbContext and all repositories are initialized in the UnitOfWork class , and I saw there is no place for dependency injection here . Is there is a way to use dpendency injection or there is no need and why?
Here is the implementation of unit of work if you are using DbContext :
class UnitOfWork : IDisposable
{
private readonly DbContext _yourDbContext;
public UnitOfWork(DbContext yourDbContext)
{
_yourDbContext = yourDbContext
}
public void Save()
{
_yourDbContext.Save();
}
void Dispose()
{
_yourDbContext = null;
}
}
public interface IUnitOfWork
{
void Save();
}
Uses :
IUnitOfWork _uow;
_yourStudentRepository.Add(Student);
_yourAddressRepository.Add(Address);
_uow.Save();
You can create the DI if you want.
public class UnitOfWork : IDisposable
{
private ISchoolContext _context;
public UnitOfWork(ISchoolContext context)
{
_context = context;
}
}
Then in your controller you can inject the Unit of Work too in the same way.
You can do all that stuff, now the question is if you need that fancy DI, personally I would, but that is up to you and your needs.
Related
Having some architecture issues that I'm trying to work through. I need to find a better way to do what I'm trying to do.
Below is a brief mockup of how my services/repos look. My problem is I am getting a circular reference when activating them. The problem is there is code in each service that I need for example in the LoadService I may need to trigger a method in the CustomerService and vice versa.
Need help to understand the best approach here. I am trying to get these services in a SRP as much as possible.
LoadRepository
public class LoadRepository
{
private readonly DBContext _DBContext;
public LoadRepository(DBContext DBContext)
{
_DBContext = DBContext;
}
public override DbSet<LoadEntity> LoadDbSet()
{
return _DBContext.Load;
}
}
LoadService
public class LoadService
{
private readonly LoadRepository _loadRepository;
private readonly ICustomerService _customerService;
public LoadService(
LoadRepository loadRepository,
ICustomerService customerService
)
{
_loadRepository = loadRepository;
_customerService = customerService;
}
}
CustomerRepository
public class CustomerRepository
{
private readonly DBContext _DBContext;
public CustomerRepository(DBContext DBContext)
{
_DBContext = DBContext;
}
public override DbSet<CustomerEntity> LoadDbSet()
{
return _DBContext.Customer;
}
}
CustomerService
public class CustomerService
{
private readonly CustomerRepository _customerRepository;
private readonly ILoadService _loadService;
public CustomerService(
CustomerRepository customerRepository,
ILoadService loadService
)
{
_customerRepository = customerRepository;
_loadService = loadService;
}
}
In my personal experience it is better to avoid dependencies on the same level referencing each other. Move common functionality into some helper classes and/or inject all needed repositories into the corresponding services. For example :
public class LoadService
{
private readonly LoadRepository _loadRepository;
private readonly CustomerRepository _customerRepository;
public LoadService(
LoadRepository loadRepository,
CustomerRepository customerRepository
)
{
_loadRepository = loadRepository;
_customerRepository = customerService;
}
}
Another approach to mitigate the problem (if currently refactoring is to much of headache) - use lazy injection via factories, for example something like the following using factory via Func:
// default DI does not provide automatic Func registration
Services.AddScoped<Func<ICustomerService>>(sp => () => sp.GetRequiredService<>(ICustomerService))
public class LoadService
{
private readonly LoadRepository _loadRepository;
private readonly Func<ICustomerService> _customerServiceFactory;
public LoadService(
LoadRepository loadRepository,
Func<ICustomerService> customerService
)
{
_loadRepository = loadRepository;
_customerServiceFactory = customerService;
}
}
And when it is needed invoke the factory - _customerServiceFactory().SomeMethod(). Though note that this method can result in SO if you have cycle in invocations (i.e. ICustomerService.Foo() calls ILoadService.Bar() which calls ICustomerService.Foo()) which can be caught only in runtime.
I have a factory to create a Generic service:
public static class AdPersisterFactory<TEntity>
where TEntity : AdBase
{
public static AdPersister<TEntity> Create(ApplicationDbContext dbContext)
{
AdRepository<TEntity> adRepository = new AdRepository<TEntity>(dbContext);
IAdImagePersister s3AdImagePersister = new S3AdImagePersister();
AdPersister<TEntity> adPersister = new AdPersister<TEntity>(adRepository, s3AdImagePersister);
return adPersister;
}
}
I want to use ninject (version 3), how can I bind IAdPersister to an instance that the above factory creates... This is my DI Code:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ApplicationDbContext>().ToSelf().InRequestScope();
// I have tried the following which does not compile
// kernel.Bind(typeof(IAdPersister<>)).ToMethod(ctx => AdPersisterFactory<>.Create(new ApplicationDbContext()));
}
This is for an ASp.NET MVC application, so ideally I don't want to use new ApplicationDbContext but use the same ApplicationDbContext which exists in RequestScope.
I have also seen Ninject.Extensions.Factory but I am not sure how/if I can use it in this scenario.
If you are willing to refactor to a more SOLID approach and AdRepository<TEntity> has a backing interface like
public class AdRepository<TEntity> : IAdRepository<TEntity>
where TEntity : AdBase {
public AdRepository(ApplicationDbContext dbContext) {
//...
}
}
And assuming...
public class AdPersister<TEntity> : IAdPersister<TEntity>
where TEntity : AdBase {
public AdPersister(IAdRepository<TEntity> adRepository, IAdImagePersister imagePersister) {
//...
}
//...
}
Then a way to create your open generic dependency would look like
private static void RegisterServices(IKernel kernel) {
kernel.Bind<ApplicationDbContext>().ToSelf().InRequestScope();
kernel.Bind<IAdImagePersister>().To<S3AdImagePersister>();
//Open generic bind for repository and ad persister
kernel.Bind(typeof(IAdRepository<>)).To(typeof(AdRepository<>));
kernel.Bind(typeof(IAdPersister<>)).To(typeof(AdPersister<>));
}
Now where ever the persister is needed you simple inject the closed type as
ctor(IAdPersister<Foo> fooPersister)
And the necessary dependencies will be resolved and injected by the container.
There really is no need for that static factory.
UPDATE
Based on comment I still advise to not have the static factory.
If you want to keep implementation details internal to your library then make the factory an instance class
public class AdPersisterFactory<TEntity> : IAdPersisterFactory<TEntity>
where TEntity : AdBase {
private readonly ApplicationDbContext dbContext;
public AdPersisterFactory(ApplicationDbContext dbContext) {
this.dbContext = dbContext;
}
public IAdPersister<TEntity> Create() {
AdRepository<TEntity> adRepository = new AdRepository<TEntity>(dbContext);
IAdImagePersister s3AdImagePersister = new S3AdImagePersister();
AdPersister<TEntity> adPersister = new AdPersister<TEntity>(adRepository, s3AdImagePersister);
return adPersister;
}
}
That can be registered as an open generic in your composition root.
private static void RegisterServices(IKernel kernel) {
kernel.Bind<ApplicationDbContext>().ToSelf().InRequestScope();
kernel.Bind(typeof(IAdPersisterFactory<>)).To(typeof(AdPersisterFactory<>));
}
and used
ctor(IAdPersisterFactory<Foo> fooPersisterFactory) {
IAdPersister<Foo> fooPersister = fooPersisterFactory.Create();
//...
}
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
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>();
}
}
I have these classes:
public static class UnitOfWorkSS
{
public static IUnitOfWork Begin()
{
return IoC.Resolve<IUnitOfWork>();
}
}
public class PostService
{
using (IUnitOfWork unitOfWork = UnitOfWorkSS.Begin())
{
//don't forget to sanitize html content
htmlContent = _htmlSanitizer.Sanitize(htmlContent);
IPost post = _factory.CreatePost(byUser, title, htmlContent);
_postRepository.Add(post);
unitOfWork.Commit();
}
}
How can I mock the classes UnitOfWorkSS and unitOfWork?
It looks like the only thing you are doing with the call to Begin() is returning your configured class for that particular interface: IUnitOfWork
You really just need to make sure that your call to Begin() returns a mock implementation of IUnitOfWork
One of two ways you can do this:
Option One - Refactor UnitOfWorkSS so that you can set the instance of IUnitOfWork to be returned
public static class UnitOfWorkSS
{
private static IUnitOfWork _unitOfWork;
public static IUnitOfWork UnitOfWork
{
set { _unitOfWork = value; }
private get{ _unitOfWork ?? (_unitOfWork = IoC.Resolve<IUnitOfWork>()); }
}
public static IUnitOfWork Begin()
{
return UnitOfWork;
}
}
[TestMethod]
public void DoStuff()
{
var mockUnitOfWork = new Mock<IUnitOfWork>();
UnitOfWorkSS.UnitOfWork = mockUnitOfWork.Object;
//Do some setup and verify
}
Option Two - Simply register a mock instance of IUnitOfWork with your IoC Container
private Mock<IUnitOfWork> _mockUnitOfWork;
[TestInitialize]
public void Init()
{
_mockUnitOfWork = new Mock<IUnitOfWork>();
//Making a lot of assumptions about your IoC here...
IoC.Register<IUnitOfWork>(_mockUnitOfWork.Object);
}
[TestMethod]
public void DoStuff()
{
_mockUnitOfWork.Setup( ... );
//Do some verification
}
Mock the IUnitOfWork and register it into your container so that it can be resolved.
As far as I know, you cannot mock static classes or methods.
I realize this is a very old question, but in case someone ends up here...
The best solution is a design change like the other answers say. However, if that's not possible, you can either use Microsoft Fakes (which replaced Moles) or, if you'd rather not depend on Visual Studio, there is a library called Smocks that can help.
https://github.com/vanderkleij/Smocks