i am about to learn IoC and Dependency Injection. And i am wondering if i understood the priciple an the pattern right.
I try to implement a UnitOfWork / Repository Pattern. I want two implementations of my Repository Classes for Unit Testing, and i want the UnitOfWork to "decide" which Concrete Implementation to instantiate (with the Help of Unity).
Example
The IUserRepository Interface
public interface IUserRepository
{
List<User> getAll();
}
The Repository Implementation using real data
public class UserRepository : IUserRepository
{
private MyDbContext db;
public UserRepository(MyDbContext db)
{
this.db = db;
}
public List<DomainModel.User> getAll()
{
return db.Users.ToList();
}
}
The FakeRepository Implementation
public class FakeUserRepository : IUserRepository
{
private List<User> userSet;
public FakeUserRepository()
{
// Fake Data
userSet = new List<User>();
userSet.Add(new User { Username = "john", Active = true, EMail = "john#ann.net", Password = "supersecret" });
userSet.Add(new User { Username = "ashley", Active = true, EMail = "ashley#ann.net", Password = "supersecret" });
userSet.Add(new User { Username = "kaidan", Active = true, EMail = "kaidan#ann.net", Password = "supersecret" });
userSet.Add(new User { Username = "tali", Active = true, EMail = "tali#ann.net", Password = "supersecret" });
}
public List<DomainModel.User> getAll()
{
return userSet;
}
}
My UnitOfWork Implementation using Unity
// To Keep it simple, i skipped the IDisposable part ;)
public class UnitOfWork
{
MyDbContext db;
private IUserRepository userRepository;
UnityContainer container = new UnityContainer();
public UnitOfWork(bool fake = false)
{
if (fake)
{
container.RegisterType<IUserRepository, FakeUserRepository>();
}
else
{
db = = new MyDbContext();
container.RegisterType<IUserRepository, UserRepository>(new InjectionConstructor(db));
}
}
public IUserRepository UserRepository
{
get
{
if (userRepository == null)
{
userRepository = container.Resolve<IUserRepository>();
}
return userRepository;
}
}
public void Save()
{
db.SaveChanges();
}
}
Now when i call new UnitOfWork() it will give me the "UnitOfWork with RealData" Implementation. If i call new UnitOfWork(fake: true) it will give me the "UnitOfWork with Fake Data". So far so good. But is this the way Unity and DI should be used? If my Application grows to say 30 Repositories do i end up defining large "If/else" Blocks, right? And imagine a want do add more data stores like XML or WCF as Source for Data. If i continue to use it like above, i will end up with a very complex and blown UnitOfWork Class.
First: I am not sure if i understood DI and Unity as it's ment to be used. If i understood it right: would it be better to use a Factory that gives me the right Type of UnitOfWork?
Any Help or tip is very welcome.
Thanks,
Matze
I would separate the Unit of Work like you did with the repositories: an IUnitOfWork interface and concrete classes for the fake and the Entity Framework Unit of Work. The Unit of Work you have now violates the Single Responsibility Principle because it has multiple responsibilities:
Pass the save call to the Entity Framework Unit of Work
Determining if the Unit of Work is fake or real
Registering the repositories on the Unity container
If you have a separate Unit of Work for Entity Framework, you won't need the container to resolve the repositories from, but you can make them member variables which you initialize in your constructor. You only have to register the correct Unit of Work on the container.
Related
I'm developing an application with .NET Core and EF. I'm trying to implement some unit test using FakeItEasy and NUnit. Here's my problem.
I've a DbContext as this one:
public class PostgresDbContext : IdentityDbContext<User, IdentityRole<int>, int> {
// Add DbSets
public virtual DbSet<Institution> Institutions { get; set; }
public virtual DbSet<Employee> Employees { get; set; }
...
Then I've a repository that uses PostgresDbContext:
public class UserRepository {
private readonly PostgresDbContext _dbContext;
public UserRepository(PostgresDbContext dbContext) {
_dbContext = dbContext;
}
...
And finally I've a service (the class that I'm trying to test) which uses UserRepository.
public class AuthService : BaseServiceAbstract {
private readonly SignInManager<User> _signInManager;
private readonly UserRepository _userRepository;
public AuthService(SignInManager<User> signInManager, UserRepository userRepository) {
_signInManager = signInManager;
_userRepository = userRepository;
}
The problem is when I try to Mock UserRepository in the following method:
[Test, Description("Should login when provided with right credentials")]
public void Login() {
var user = new Employee {Name = "user"};
var signInManger = A.Fake<SignInManager<User>>();
var userRepository = A.Fake<UserRepository>();
_authService = new AuthService(signInManger, userRepository);
A.CallTo(() => userRepository.FindUserByUsername("user"))
.Returns(user);
_authService.Login("user", "password");
}
I throws me the error:
FakeItEasy.Core.FakeCreationException :
Failed to create fake of type DAL.Repositories.UserRepository:
The constructors with the following signatures were not tried:
(*DAL.PostgresDbContext)
Types marked with * could not be resolved. Please provide a Dummy Factory to enable these constructors.
Any idea?
To create a fake UserRepository, FakeItEasy needs an instance of PostgresDbContext. So it tries to create a fake one, but doesn't succeed (I don't have enough details to determine why exactly). Anyway, mocking a DbContext is always difficult.
Instead of mocking UserRepository directly, consider introducing a IUserRepository interface, implemented by UserRepository, and inject that in your AuthService. Mocking interfaces is generally much easier than mocking classes.
In general, you should avoid making your classes depend on other concrete classes. They should depend on abstractions instead. This will make your life much easier when writing unit tests.
Trying to use autofac for dependency injection by property.
The instance is always null and there is no dependency injected.
Below is class where the property needs to be injected.
public class UserAccount
{
public IAccountService AccountService { get; set; }
public string Message()
{
return AccountService.Message();
}
}
I have tried three different ways to inject the property but none was successful
Method 1 :
builder.Register(c => {
var result = new UserAccount();
var dep = c.Resolve<IAccountService>();
result.SetDependency(dep);
return result;
});
Method 2 :
builder.RegisterType<UserAccount>().PropertiesAutowired();
Method 3 :
builder.Register(c => new UserAccount { AccountService = c.Resolve<IAccountService>()});
PS : Method injection of above is welcomed.
You should prevent letting your container create data-centric objects, such as your UserAccount entity. This leads to complicated scenarios, such as the one you are in now.
In general, your DI Container should resolve only components—those are the classes in your system that contain the application's behavior, without having any interesting state. Those types of classes are typically long lived, or at least, longer lived than data-centric objects.
Data-centric objects, like entities, can best be created by hand. Not doing so would either lead to entities with big constructors, which easily causes the constructor over-injection code smell. As remedy, you might fall back on using Property Injection, but this causes a code smell of its own, caused Temporal Coupling.
Instead, a better solution is to:
Create entities by hand, opposed to using a DI Container
Supply dependencies to the entity using Method Injection, opposed to using Property Injection
With Method Injection, your UserAccount would as follows:
// This answer assumes that this class is an domain entity.
public class UserAccount
{
public Guid Id { get; set; }
public byte[] PasswordHash { get; set; }
public string Message(IAccountService accountService)
{
if (accountService == null)
throw new ArgumentNullException(nameof(accountService));
return accountService.Message();
}
}
This does move the responsibility of supplying the dependency from the Composition Root to the entity's direct consumer, though. But as discussed above, this is intentional, as the Composition Root in general, and a DI Container in particular, should not be responsible of creating entities and other data-centric, short-lived objects.
This does mean, however, that UserAccount's direct consumer should inject that dependency, and with that, know about existence of the dependency. But as that consumer would be a behavior-centric class, the typical solution is to use Constructor Injection at that stage:
public class UserService : IUserService
{
private readonly IAccountService accountService;
private readonly IUserAccountRepository repo;
public UserService(IAccountService accountService, IUserAccountRepository repo)
{
this.accountService = accountService;
this.repo = repo
}
public void DoSomething(Guid id)
{
UserAccount entity = this.repo.GetById(id);
var message = entity.Message(this.accountService);
}
}
Using method 3, you need to register AccountService, i.e.
builder.RegisterType<AccountService>().As<IAccountService>();
builder.Register(c => new UserAccount { AccountService = c.Resolve<IAccountService>()});
And when you use UserAccount, make sure it is created using Autofac.
I have some code (C# .Net Core WebAPI) I wish to unit test but need some help as the dependencies looks a bit odd to me.
The code came from some sample code (I found on the web) for accessing MongoDb using .Net Core WebAPI, which initially looked ok, until now..
Both the DbContext and the Repository have the same dependency - and the Repository just passes it through to the DbContext anyway - as the Repository instantiates the DbContext:
public class LogItemRepository : ILogItemRepository
{
private readonly DbContext _context = null;
public LogItemRepository(IOptions<DbSettings> settings)
{
_context = new DbContext(settings);
}
...
public class DbContext
{
private readonly IMongoDatabase _database = null;
public DbContext(IOptions<DbSettings> settings)
{
var client = new MongoClient(settings.Value.ConnectionString);
if (client != null)
_database = client.GetDatabase(settings.Value.Database);
}
public IMongoCollection<LogItem> LogItemsCollection
{
get
{
return _database.GetCollection<LogItem>("LogItem");
}
}
}
}
I'm not familiar with the Options pattern, but from a quick read it looks good. But I'm not convinced it's good practice to make child dependencies (the options), dependencies of the parent (as in the example above).
Instead should I be making an interface, IDbContext, and using that as the dependency for the repository? That's what I would have done in the past - but not sure if this breaks the options pattern.
I suspect this is subjective, but I'd like some others input.
Thanks
Tim
While primarily opinion based, common practice is to not instantiate the db context within the constructor of the repository. That tightly couples the repository to the context. Inject an abstraction as you stated in your OP.
I may be splitting hairs here but there is still too much tight coupling in the example provided.
First abstract the context
public interface IDbContext {
IMongoCollection<LogItem> LogItemsCollection { get; }
}
and also have IMongoDatabase be an explicit dependency
public class DbContext : IDbContext {
private readonly IMongoDatabase database = null;
public DbContext(IMongoDatabase database)
this.database = database;
}
public IMongoCollection<LogItem> LogItemsCollection {
get {
return database.GetCollection<LogItem>("LogItem");
}
}
}
configure service with what ever options are needed at the composition root (Startup). You would even consider encapsulating it in an extension method.
services.AddScoped<IMongoDatabase>(provider => {
var settings = provider.GetService<IOptions<DbSettings>>();
var client = new MongoClient(settings.Value.ConnectionString);
return client.GetDatabase(settings.Value.Database);
});
services.AddScoped<IDbContext, DbContext>();
services.AddScoped<ILogItemRepository, LogItemRepository>();
//...NOTE: Use the desired service lifetime. This is just an example
That now leaves the repository to be explicitly dependent on the context abstraction
public class LogItemRepository : ILogItemRepository {
private readonly IDbContext context = null;
public LogItemRepository(IDbContext context) {
this.context = context;
}
//...other code
}
All layers are now decoupled and explicitly state what their dependencies are, allowing for more isolated unit tests to be done as needed.
I'm using Repository and UoW pattern. My services look like this:
public class MyService : IService
{
private readonly IUnitOfWork<MyContext> unitOfWork;
private readonly IMyRepository myRepository;
public MyService(IUnitOfWork<MyContext> unitOfWork, IMyRepository myRepository)
{
this.unitOfWork = unitOfWork;
this.myRepository = myRepository;
}
//Methods...
}
Within services, I need to use other entities (for example to check for rights, etc).
Is it recommended to use the relevant repositories in the service or use the services directly?
Also, for each user we have rights (boolean) for each CRUD action. These rights are stored in the database.
Should checking of rights be done at the controller level or at the service level?
My golden rule is:
When you get business logic in your UI create a service, otherwise use
the repository directly.
So if you have this code in the UI:
var user = repos.Get(1);
user.FirstName = txtFirstName.Text;
repos.Save(user);
You are fine in my opinion. But if you instead have something like:
var user = userRepository.Get(1);
var accessChecker = authorizationRepository.GetForUser(id);
if (!accessChecker.MaySendEmail(user))
throw new SecurityException("You may not send emails");
var emailSender = new EmailSenderService();
emailSender.Send(user, txtDestination.Text, txtMessage.Text);
repos.Save(user);
It's likely that you should use a service instead.
Don't use your UoW to just wrap your database context. Since all your repositories are directly dependent of a given context (more or less, ofc), your repositories can be included in the UoW. Something along the lines of:
public interface IUnitOfWork<TContext> : IDisposable { }
public abstract class UnitOfWork<TContext> : IUnitOfWork<TContext> {
private readonly TContext _context;
protected TContext Context { get{ return _context; } }
protected UnitOfWork(TContext context){
_context = context;
}
}
public interface IMyDbUnitOfWork : IUnitOfWork<MyContext>{
public ICarRepository Cars { get; }
public IOwnerRepository Owners { get; }
}
public class MyDbUnitOfWork : UnitOfWork<MyContext>, IMyDbUnitOfWork{
public MyDbUnitOfWork():base(new MyContext()){}
private ICarRepository _cars;
public ICarRepository Cars {
get{
return _cars ?? (_cars = new CarRepository(Context));
}
}
private ICarRepository _owners;
public IOwnerRepository Owners {
get{
return _owners ?? (_owners = new OwnerRepository(Context));
}
}
}
public class MyService : IService
{
private readonly IMyDbUnitOfWork _unitOfWork;
public MyService(IMyDbUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
//Methods...
}
Obviously you can create this more or less generic, but I believe this should be enough to pass my point.
As a note, and since I normally use IoC frameworks, my services receive an IUnitOfWorkFactory because of the diferent lifestyles.
For the permissions question, it really depends how much control you want to have and how user friendly you want your application to be. Normally is a mix of both. Your application should know if your user has access to the screen but also if you must disable buttons accordingly. Since you also must prevent that, if by any reason, the user can invoke your service method, you can't allow it.
To solve this problem I don't filter by CRUD actions but by Service actions instead, intercepting every service invocation, which makes it easy to map my permissions to the user interface since normally is a 1 to 1 relation between button action and service action.
I think using repositories is just fine. I wouldn't invent a service layer for each of the repos.
Repository is used for abstracting the data access and service layer is to encapsulate business logic, however with recent trend , I find this overkill. Having service layer is fine if they act as controllers but don't try to map one to one to each entity or repo.
I typically use services from the UI and those services in turn use the repositories. I also find it useful to have some domain objects that encapsulate reusable logic in the services.
I do this so that rather than services calling each other and getting circular references, services use a common domain object instead. This avoids circular references and people copying and pasting the same code all over the place.This domain object may then use the repositories if necessary.
I have a simple repository that fetches some data using EF6. I'm also using a DI framework to inject the dependencies.
namespace Domain
{
public interface IMyRespository
{
List<MyObject> FetchObjects();
}
}
namespace Data
{
public class MyRepository : IMyRepository
{
private readonly MyDbContext _context;
public MyRepository(MyDbContext context)
{
_context = context;
}
public List<MyObjects> FetchObjects()
{
return _context.MyObjects.ToList();
}
}
}
A new requirement states that I need to log each FetchObjects() call and it's outputs. I thought this would be perfect example to apply the Decorator pattern.
namespace Domain
{
public class MyRepositoryDecorator : IMyRepository
{
private readonly IMyRepository _inner;
private readonly ILogRepository _logRepository;
public MyRepositoryDecorator(IMyRepository inner, ILogRepository logRepository)
{
_inner = inner;
_logRepository = logRepository;
}
public List<MyObjects> FetchObjects()
{
var objects = _inner.FetchObjects();
var logObject = new LogObject(objects);
_logRepository.Insert(logObject);
_logRepository.Save();
return objects;
}
}
}
Now I'm looking to employ the UnitOfWork pattern and I'm unsure how to implement in this case.
As I understand it some component needs to manage the UnitOfWork. So in this case a service class would make some calls and at the end call Save/Commit on the UnitOfWork class.
However if the repository interface indicates a readonly action there is no reason for the service class to wrap the call in a UnitOfWork and call Save/Commit at the end. It would look really weird too. However the decorator requires this to do it's job.
I'm probably missing some essential construct here. Any ideas on how to properly approach this scenario?
It would be a bad idea to mix UoW with Repository using Decorator (or similar) simply because it is not unusual for UoW to span across multiple repositories.
Also it is not up to the Repository to decide whether UoW should be committed or not. Repositories should know as less as possible about UoWs, ideally (and it is the case most of the time) nothing.
In your scenario the UnitOfWork class would pretty much only handles the transaction, so it can be implemented as a simple wrapper around TransactionScope, something like:
public sealed class UnitOfWork : IDisposable {
private readonly TransactionScope _transaction;
public UnitOfWork() { _transaction = new TransactionScope(); }
public void Commit { _transaction.Commit(); }
public void Dispose { _transaction.Dispose(); }
}
Now it is up to the service to instantiate/commit UoW, not up to Repository:
//assuming in a service
public void DoSomething() {
using(var uow = new UnitOfWork()) {
_repositoryA.UpdateSomething();
_repositoryB.DeleteSomething();
_uow.Commit();
}
}
And if your service only wants to read the data, then just do not use UnitOfWork in that operation (or use it without calling Commit so it will just be disposed).
In case if your repository needs to know about UoW, it will normally be passed as another parameter in its behavior method.
Note that it is not done because Repository wants to call Commit, but sometimes (rarely) it is needed for the repository to "enlist" to UoW. These cases are rather more complex.