I am following a tutorial to do with the Repository Pattern in a combination with the Unit Of Work pattern.
I essentially have:
interface IRepository<T> where T : class
{
//...
}
class Repository<T> where T : class
{
//Implemented methods
}
interface IFooRepository
{
IQueryable<Foo> GetFoos();
}
class FooRepository : Repository<Foo>, IFooRepository
{
IQueryable<Foo> GetFoos() {}
}
The above represents my repositories, in a basic sense. I then have a Uow class.
public class MyUow
{
public void Commit() { }
public IRepository<Bar> Bars { get { return GetStandardRepo<Bar>(); } }
public IFooRepository Foos { get { return GetRepo<IFooRepository>(); } }
private IRepository<T> GetStandardRepo()
{
return RepositoryProvider.GetRepoistoryForEntityType<T>();
}
private T GetRepo<T>()
{
return RepositoryProvider.GetRepository<T>();
}
}
My problem is coming where the tutorial I am following only ever instansiates a Dictionairy<Type, object> in the RepositoryProvider class and doesn't seem to fill it, so the method used in GetRepo<T> doesn't work.
public virtual T GetRepository<T>(Func<DbContext, object> factory = null) where T : class
{
//Look for T in the dictionairy by typeof(T)
object repoObj;
Repositories.TryGetValue(typeof(T), out repoObj);
if (repoObj != null)
return (T)repoObj;
//Not found or a null value, make a new instance of the repository.
return MakeRepository<T>(factory, Context);
}
private T MakeRepository<T>(Func<DbContext, object> factory, DbContext dbContext) where T : class
{
var f = factory ?? _repositoryFactories.GetRepositoryFactory<T>();
if (f == null)
//Exception here because this is null
throw new NotImplementedException("No factory for repository type");
var repo = (T)f(dbContext);
Repositories[typeof(T)] = repo;
return repo;
}
My question is essentially what is the correct way to implement this pattern and where I am going wrong? Should I instansiate the Dictionairy<Type, Func<DbContext, object> with a the list of known repositories? This seems dirty. I am driving myself insane trying to solve this!
Thanks in advance.
What I see from beginning is that your Repository<T> doesn't implement IRepository<T>, so it should be like this:
class Repository<T> : IRepository<T> where T : class
{
//Implemented methods
}
Then your completely secret tutorial should describe how _repositoryFactories.GetRepositoryFactory<T>() can discover your IRepository<T> implementor FooRepository - maybe it willbe autodiscovery, maybe you need to register something somewhere.
Next, again I know nothing about your specific tutorial and factories etc, but I suppose you may need to use GetRepo<Foo> instead of GetRepo<IFooRepository>, because right now this IFooRepository looks meaningless... or maybe again you miss something in this IFooRepository declaration, and it should be like interface IFooRepository : IRepository<Foo> - and again, it greatly depends on particular discovery implementation for factories you are using.
In case you have not found the answer yet, I followed through the tutorial and was able to run it (the tutorial sample). If you're sure that you have implemented it right, take note of this,
The Repository Dictionary is by default, null and will only have value of the not standard repos (e.g. IFooRepository) when it is first requested. Therefore, if you're checking the value in debug of the Repository Dictionary and an IFooRepository is not yet requested it is for sure that you will not see it there. Have a code to access the IFooRepository first then it will make a repository for that in the MakeRepository method of the provider class.
Hope that helps
There is a helper class called RepositoryFactories.cs
You need to add an entry for your custom Repository to the dictionary
{typeof(IFooRepository ), dbContext => new FooRepository (dbContext)}
Related
We have an interface to deal with DAL with pretty simple definition:
interface IRepository<T> : IQueriable<T> // so we can read data from database
{
Save(T document); // dozen of methods here
}
Mostly we use two implementations: real version and in memory version for unit testing. Here is declarations of one of class:
public RealRepository : IRepository<AccountEntity> { ... }
// typical IOC usage
services.AddSingleton<IRepository<AccountEntity>, RealRepository<AccountEntity>>();
Now we are working to spin off for main codebase to custom version of project and we need custom fields in data and occassional custom behavior in repository. Most of classes are fine with base implementation but others would require specific implementation. So my goal is to get to following services in:
var repository = new RealRepository<CustomAccountEntity>();
services.AddSingleton(IRepository<AccountEntity>, repository);
// for new classes
services.AddSingleton(IRepository<CustomAccountEntity>, repository);
I tried to add out T to IRepository but I am using T in input parameters and this gave compile time "Invalid variance" error.
I can see a solution by adding second type parameter to interface so it looks like:
IRepository<TBase, out TChild> : IQueriable<TChild> {
Save (T document);
}
Finally, Question: How can make change 100% backward compatible?
What I tried:
Add IRepository<T>: IRepository<T,T> -> complies, but RealRepository is not implementing IRepository anymore.
Add 2 interfaces in implementation: public class RealRepository<TBase, TChild>: IRepository<TBase, TChild>, IRepository<TChild> but this gives compliation error 'cannot implement both ... and ... because they may unify for some type parameter substitutions'
Save(T document) has T in a contravariant position. That means in T, not out T.
Let's recap what contravariance means. Suppose you had this code:
using System;
public class Entity {}
public class AccountEntity : Entity {}
public class CustomAccountEntity : AccountEntity {}
public interface IQueryable<in T>
where T : Entity
{}
public interface IRepository<in T>
where T : Entity
{
void Save(T record);
}
public class EntityRepository<T> : IRepository<T>
where T : Entity
{
public void Save(T record) {}
}
public class Program
{
public static void Main()
{
// This is ***VALID***:
IRepository<CustomAccountEntity> repo = new EntityRepository<AccountEntity>();
Console.WriteLine(repo == null ? "cast is invalid" : "cast is valid");
}
}
https://dotnetfiddle.net/cnEdcm
So whenever you need a IRepository<CustomAccountEntity>, you can use a concrete EntityRepository<AccountEntity> instance. Seems counter-intuitive, but it's actually totally right: If the concrete method is Save(AccountEntity), it can obviously handle CustomAccountEntity instances too; OTOH if the concrete method were Save(CustomAccountEntity), it would NOT be able to handle simple AccountEntity instances.
Having said that, then I think you should
Use contravariance instead;
Declare all dependencies using the most specialised type, e.g. IRepository<CustomWhateverEntity>;
In the IoC registration code, for each particular entity, setup either Repository<CustomeWhateverEntity>, if you need the extra behaviour, or just Repository<WhateverEntity> otherwise.
I'm trying to implement the Dependency Injection from Core on my software in order to replace Ninject and update everything to our new technology.
Btw, I'm facing a problem on some interfaces that are generic. For such cases I'm getting directly an Exception that the injector could not create an instance of my class.
I inserted above a small snippet of a sample case that puts me on fire.
services.AddTransient(typeof(IRepository), typeof(MyRepository<,>))
Is that way correct? How can I do that?
Class implementation:
public class MyRepository<TEntity, TContext> : IRepositoryBase
where TEntity : class
where TContext : IDbContext, new()
{
...
}
Interface:
public interface IRepository : IDisposable
{
...
}
Thanks!
This doesn't really make sense. You will be asking the container for IRepository, so how would it know what the generic type arguments should be such that it can give you a MyRepository<,>?
So when asked to return an object like this:
public class MyService
{
private IRepository<Something, SomethingElse> _repo;
public MyService(IRepository<Something, SomethingElse> repo)
{
// Container will actually give us MyRepository<Something, SomethingElse>
_repo = repo;
}
}
I would expect either:
services.AddTransient(typeof(IRepository<,>), typeof(MyRepository<,>));
or, if your repository doesn't need to be generic (I don't understand why it'd need two generic arguments as it is), then I'd expect this:
services.AddTransient(typeof(IRepository), typeof(MyRepository));
However, since there's no generics involved here, you could use the alternative form to achieve the same thing with less typing:
services.AddTransient<IRepository, MyRepository>();
So really the answer is to solve your interface/class design. Showing more of the implementation of them would help.
UPDATE
Your implementation needs to be:
Class implementation:
public class MyRepository<TEntity, TContext> : IRepository<TEntity, TContext>
where TEntity : class
where TContext : IDbContext, new()
{
...
}
Interface:
public interface IRepository<TEntity, TContext> : IDisposable
where TEntity : class
where TContext : IDbContext, new()
{
...
}
I ended up using Autofac and without any changes on my structure everything started working again.
Will wait a little more for documentation and more people using, so I can change my implementation to use MS DI.
To register all repositories use this:
var allRepositories = GetType().GetTypeInfo()
.Assembly.GetTypes().Where(p =>
p.GetTypeInfo().IsClass &&
!p.GetTypeInfo().IsAbstract &&
typeof(IRepository).IsAssignableFrom(p));
foreach (var repo in allRepositories)
{
var allInterfaces = repo .GetInterfaces();
var mainInterfaces = allInterfaces.Except
(allInterfaces.SelectMany(t => t.GetInterfaces()));
foreach (var itype in mainInterfaces)
{
services.AddScoped(itype, repo);
}
}
Then resolve it:
public YourClass(IRepository<T> repo)
{
//...
}
I have a question about creating a factory interface with a create method that can cater for accepting different argument types depending on the implementation.
To give you a bit more background, I am using dependency in injection in a project, and require stateful objects to be generated at runtime - therefore I am injecting factories (rather than the objects themselves) to create these stateful objects. The problem I have come across is that, for some interfaces, the concrete implementations simply cannot have the same constructor argument types, and so the factories that create an instance of these interfaces require almost 'dynamic' arguments to be passed to the create method.
I have been going over this for a couple of days, and the following is the best solution I could come up with (namely, passing an object to the factory create method and casting it in the concrete implementation of the factory). I am really looking for feedback from people who have come across this scenario before, to hear what they came up with, and whether or not the solution I am proposing below is acceptable.
Apologies if this is missing any information, and many thanks in advance!
//
// Types...
//
interface IDataStore
{
List<string> GetItems();
}
public class XmlDataStore : IDataStore
{
public XmlDataStore(XmlDocument xmlDoc)
{
// Initialise from XML Document...
}
public List<string> GetItems()
{
// Get Items from XML Doc...
}
}
public class SQLDataStore : IDataStore
{
public SQLDataStore(SqlConnection conn)
{
// Initialise from SqlConnection...
}
public List<string> GetItems()
{
// Get Items from Database Doc...
}
}
//
// Factories...
//
interface IDataStoreFactory
{
IDataStore Create(object obj);
}
class XmlDataStoreFactory : IDataStore
{
IDataStore Create(object obj)
{
// Cast to XmlDocument
return new XmlDataStore((XmlDocument)obj);
}
}
class SQLDataStoreFactory : IDataStore
{
IDataStore Create(object obj)
{
// Cast to SqlConnection
return new SQLDataStore((SqlConnection)obj);
}
}
Based on this comment you need one factory which produces several types of IDataStore. You could accomplish by creating a open generic factory method in the singleton factory instance.
interface IDataStore<TStoreType>
{
void SetBaseType(TStoreType obj);
List<string> GetItems();
}
interface IDataStoreFactory
{
IDataStore<TStoreType> Create<TStoreType>(TStoreType obj)
}
class DataStoreFactory : IDataStoreFactory
{
public IDataStore<TStoreType> Create<TStoreType>(TStoreType obj)
{
if (obj.GetType() == typeof(SqlConnection))
{
var store = new SQLDataStore((SqlConnection)(Object)obj);
return (IDataStore<TStoreType>)store;
}
if (obj.GetType() == typeof(XmlDocument))
{ //... and so on }
}
}
class SQLDataStore : IDataStore<SqlConnection>
{
private readonly SqlConnection connection;
public SQLDataStore(SqlConnection connection)
{
this.connection = connection;
}
public List<string> GetItems() { return new List<string>(); }
}
You can use this factory like this:
var factory = new DataStoreFactory();
var sqlDatastore = factory.Create(new SqlConnection());
var xmlDatastore = factory.Create(new XmlDocument());
Your datastore factory would become a lot less complex if you would use a DI container. You could inject the container in the factory and retrieve your instances directly from the container, which would typically build your instances from bottom to top, including there own dependencies, lifetime management and so on. But be very carefull with this approach, it is the first step to using the service locator pattern which is an anti pattern
Not really sure if I understand your question correctly but to me it sounds a little odd to have factory instances which you use for the creation of your statefull objects as you call them.
To directly answer your question: generics are your solution. You rinterface becomes an open generic abstraction:
interface IDataStore<TStoreType>
{
List<string> GetItems();
}
interface IDataStoreFactory<TStoreType>
{
IDataStore<TStoreType> Create(TStoreType obj);
}
and your factory classes will look like this:
class XmlDataStoreFactory : IDataStoreFactory<XmlDocument>
{
IDataStore<XmlDocument> Create(XmlDocument document)
{
return new XmlDataStore(document);
}
}
class SQLDataStoreFactory : IDataStoreFactory<SqlConnection>
{
IDataStore<SqlConnection> Create(SqlConnection connection)
{
return new SQLDataStore(connection);
}
}
This will work, but from the examples you give I got the impression you're using factories throughout your codebase. Maybe I'm wrong on this point, but look at your design and minimize the number of factories. Needing a factory means mixing data with behaviour and this will always, eventually, get you into trouble.
For example, let's say you have some kind of service which adds the current user to a audit log when he logs in. This service offcourse needs the current user which is a typical example of runtime data (or contextual data). But instead of:
public class AuditLogService
{
public void AddApplicationSignIn(User user)
{
//... add user to some log
}
}
I know this is not a good example because you actually wouldn't need a factory for this class, but with the next code example you'll get the point:
public class AuditLogService
{
private readonly IUserContext userContext;
public AuditLogService(IUserContext userContext)
{
this.userContext = userContext;
}
public void AddApplicationSignIn()
{
var user = this.userContext.GetCurrentUser();
//... add user to some log
}
}
So by splitting data from behaviour you rule out the need for factories. And admitted there are cases where a factory is the best solution. I do think an IDataStore is not something you need a factory for.
For a good blog on splitting data and behaviour read here
I have classes for entities like Ship, Shampoo, Horse etc and each of them will have a manager class like ShipManager, ShampooManager, HorseManager etc. All the manager classes implement IManager and entities implement IEntity.
Now I have a static function written just to save the entities which would look like:
public static bool Save<S, T>(S entity, string msg) where S : IEntity
where T : IManager<S>, new()
{
string possibleError;
switch (new T().Save(entity, out possibleError))
{
//---------------------
}
return true;
}
The inelegance here is that I have to call the Save like Save<Radio, RadioManager> etc. What I would love to have is something like this:
public static bool Save<T>(T entity, string msg) where T : IEntity
{
string possibleError;
switch ((/*find manager here*/).Save(entity, out possibleError))
{
//---------------------
}
return true;
}
There are few ways to do this, but I would love to have something that involves generics and type inference. I am thinking it would be good to couple the entity classes with corresponding manager classes by design to achieve some type safety as well.
Here is what I could do, with the help of an extension method:
public static bool Save<T>(this IManager<T> mgr, T entity, string msg) where T : IEntity
{
string possibleError;
switch (mgr.Save(entity, out possibleError))
{
//---------------------
}
return true;
}
So that I can call:
FooManager fMgr = new FooManager();
fMgr.Save(foo, "success");
But here I always need to instantiate the IManager and then call the Save method on its instance. I would love to avoid that much repetitive code and give the duty to a static function. How can I design the classes to have a relationship between IManager and IEntity so that manager of entity is automatically inferred?
Edit: Please note that I dont have the luxury to move the Save method in manager class to entity class (which would have made life easier). Our entire design is based on one entity class and a corresponding manager class. So I am thinking of sticking to it.
Does the Client of FooManager care that it's a FooManager or that it's an IManager<Foo> ? If it just wants an IManager<Foo>, you probably want to look at the AbstractFactory pattern. Your factory would be responsible for instantiating/retrieving the correct IManager on demand. With the factory in place your save method would look something like this
public static bool Save<S>(S entity, string msg)
where S : IEntity
{
string possibleError;
switch (ManagerFactory.GetManagerFor<S>().Save(entity, out possibleError))
{
//---------------------
}
return true;
}
The simplest path for implementing your ManagerFactory is to use a service locator/dependency injector, and have it auto discover your IManager<T> implementations. Then your GetManagerFor method would just ask for an instance from the DI Container. For example, here's how to do it with AutoFac
var dataAssembly = Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(dataAssembly)
.Where(t => t.Name.EndsWith("Manager"))
.AsClosedTypesOf(typeof(IManager<>);
This will cause autofac to find all classes that end with "Manager" in their name in the current assembly and register as closed types of IManager<T>. So it would find FooManager and register it as an instance of IManager<Foo>
Now ManagerFactory just needs to call
return container.Resolve<IManager<Foo>>()
And you're golden. I'm not going to write your application for you but this should give you enough to get you going. Read the docs on AutoFac, it's really powerful because it can also build up objects for you using dependency injection as well and it's a great tool to have in your belt.
Here is how I solved it.
I created a function Manager in the IEntity like this:
IManager<T> Manager<T>() where T : IEntity;
Now whenever I implement IEntity in any of the entity classes, I am forced to implement their respective Manager as well. For eg.
public class Foo : IEntity
{
public IManager<T> Manager<T>() where T : IEntity
{
return (IManager<T>)new FooManager();
}
}
Now I can call:
public static bool Save<T>(T entity, string msg) where T : IEntity, new()
{
string possibleError;
switch (entity.Manager<T>().Save(entity, out possibleError))
{
//--------------------------------------
}
return true;
}
Not the best of designs, but this does the job..
I need some help with the design of the Unit of Work + Repository + IoC pattern. I have several interfaces defined as follows:
public interface IRepository<T>
{
T GetEntity(int id);
}
public interface IUserRepository : IRepository<User>
{
User GetUserByXyz(int id);
}
public interface IUnitOfWork
{
T Respository<T>() where T : IRepository<T>;
}
I am using Unity to resolve some references. Here's the implementation of the UoW:
public class UnitOfWork : IUnitOfWork
{
public T Respository<T>() where T : IRepository<T>
{
var container = new UnityContainer();
return container.Resolve<T>();
}
}
Now i am having trouble calling the interface:
User user = _unitOfWork.Respository<IUserRepository>().GetUserByXyz(1);
The type 'IUserRepository' cannot be used as type parameter 'T' in
the generic type or method 'IUnitOfWork.Respository()'. There is no
implicit reference conversion from 'IUserRepository' to
'IRepository'.
How do get around the generic constraint error?
Expanding on my comment:
The statement public T Respository<T>() where T : IRepository<T> implies that you're expecting a type that is a Repository of itself, e.g. IUserRepository would have to be an IRepository<IUserRepository> to satisfy your condition.
You need two different generics, one for the item that is held in the reporsitory TItem and another for the repository itself, TRepo.
Then the whole code becomes:
public interface IRepository<TItem>
{
TItem GetEntity(int id);
}
public interface IUserRepository : IRepository<User>
{
}
public interface IUnitOfWork
{
TRepo Respository<TRepo,TItem>() where TRepo : IRepository<TItm>;
}
and
public class UnitOfWork : IUnitOfWork
{
public TRepo Respository<TRepo,TItem>() where TRepo : IRepository<TItem>
{
var container = new UnityContainer();
return container.Resolve<TRepo>();
}
}
finally, the call becomes:
User user = _unitOfWork.Respository<IUserRepository,User>().GetEntity(1);
Initial note:
_unitOfWork.Respository<IUserRepository>()…
As it is, you're essentially "abusing" UnityOfWork as a service locator (you can ask it for any type of repository), but it doesn't seem to offer any additional benefits. Is this really what you want? Couldn't you just do away with UnitOfWork and do the following instead:
_unityContainer.Resolve<IUserRepository>()…
Alternative solution that does not require a second type parameter:
I agree with #Jon Egerton that for this to work correctly, one option would be to introduce a second generic type parameter (TItem next to TItemRepository). There is, however, another solution involving a marker interface IRepository:
// non-generic marker interface (empty)
public interface IRepository {}
public interface IRepository<T> : IRepository { … /* as before */ }
// ^^^^^^^^^^^^^
// added
public class UnitOfWork
{
public TRepository Get<TRepository>() where TRepository : IRepository
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// this way, no 2nd type parameter is
// needed since the marker interface is
// non-generic.
{
return new UnityContainer().Resolve<TRespository>();
}
}
As requested: Unit of Work example:
If you follow Martin Fowler's definition for the Unit of Work pattern, you get something rather different from what you've got right now. Rather, a Unit of Work according to his udnerstanding merely keeps track of all changes that have been made to a collection of objects. The idea behind this is that changes aren't persisted (e.g. to a database) one at a time, but all at the same time, when requested through the unit of work object; thus the pattern's name:
class UnitOfWork<T>
{
// the UnitOfWork object tracks changes to objects of type T:
private HashSet<T> newItems;
private HashSet<T> modifiedItems;
private HashSet<T> removedItems;
public void Commit()
{
// let's say items are persisted to an RDBMS, then:
// * generate 'DELETE FROM [tableForItemsOfTypeT]' statements
// for all items in the 'removedItems' set;
// * generate 'INSERT INTO [tableForItemsOfTypeT]' statements
// for all items in the 'newItems' set;
// * generate 'UPDATE [tableForItemsOfTypeT]' statements
// for all items in the 'modifiedItems' set.
}
}
Your definition of IUnitOfWork seems a little peculiar, and it seems you've got your generic parameter constraint wrong:
public interface IUnitOfWork
{
T Respository<T>() where T : IRepository<T>;
}
I'd try to get rid of the generic parameter constraint, if possible. For example:
public interface IUnitOfWork<T>
{
IRepository<T> Respository { get; }
}
public class UnitOfWork<T> : IUnitOfWork<T>
{
public IRepository<T> Respository
{
get
{
var container = new UnityContainer();
return container.Resolve<IRepository<T>>();
}
}
}
(Admittedly, I'm not sure whether it's a good idea to constrain a UnitOfWork class to one particular object type by parameterizing it this way. You could in theory also have a UnitOfWork class that implements IUnitOfWork<T> several times, for different T, though that's probably equally unwise. Judge yourself what is most appropriate for your purposes.)
Note that you'd then also have to register your types differently. You could possibly also get rid of IUserRepository this way.
P.S.: Probably, Repository does make more sense if it's a method, and not a property, as shown above. I'd choose based on how costly it is to "get" a repository. If it's expensive, make it a method; if it's a cheap operation, a property might be just fine. If you keep it as a method, I'd rename it to GetRepository to better adhere to the common .NET naming guidelines. Alternative approach:
public interface IUnitOfWork
{
IRepository<T> GetRespository<T>()
}
You are confusing your Generic constraint:
public T Respository<T,U>() where T : IRepository<U>
User user = _unitOfWork.Respository<IUserRepository,User>().GetEntity(1);