My repository pattern is setup like this:
public interface IRepository<T> where T : class {}
public abstract class Repository<C, T> : IRepository<T>
where C : DbContext, IBaseContext
where T : class, IEntity
{}
public interface ICustomerRepository : IRepository<Customer>
{//specific methods here}
public class CustomerRepository : Repository<MyContext, Customer>, ICustomerRepository
I added the following method in my UoW class (and interface):
public TRepository GetRepository<TEntity, TRepository>()
where TEntity : class, IEntity
where TRepository : IRepository<TEntity>
{
object[] args = new object[] { (IDatabaseFactory<MyContext>)databaseFactory };
return (TRepository)Activator.CreateInstance(typeof(TRepository), args);
}
And in my service I try to get the repository doing the following:
var customerRepository = uow.GetRepository<Customer, CustomerRepository>();
In Autofac i'm using InstancePerRequest. So the UoW and the repository instances are created per request and disposed afterwards. Do I still need to implement caching of the repositories?
Is this the correct way to use repository factory?
NOTE
My UoW and repositories are located in a 'DAL' assembly, my services are in a different 'Service' assembly.
A factory's only job is to construct instances of classes. So in that sense, your factory is correct.
Your IoC container is already managing the life time of the object so there is no need to duplicate that work.
My question is this: Why even have a factory? Your IoC container is already capable of constructing instances. Why not just request an ICustomerRepository from Autofac directly and have it construct for you, instead of requesting a custom object who's only job is to do what Autofac can do out of the box?
Related
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)
{
//...
}
Will Entity Framework dispose the SqlConnection used in the GetFooFromUnmappableEntity method?
I have the following service:
public class FooService {
private readonly FooContext fooContext;
public FooService(FooContext fooContext) {
this.fooContext = fooContext;
}
public Foo GetFooFromUnmappableEntity(int id) {
return fooContext.Database.SqlQuery<Foo>(string.Format("select * from GetFoo({0})", id);
}
}
I'm using Ninject to manage my dependencies in a class library. So A binding exists somewhere like this:
Bind<FooContext>.ToSelf();
Ninject is an implementation of "dependency inversion", which means your dependencies are interfaces and Ninject will give you the implementations. You will want to create a IFooRepository that in its implementation uses FooContext. then IFooRepository gets injected into the constructor of IFooService and IFooService doesn't need to know anything about how the repository is implemented.
As far as disposing the SqlConnection, you will want to bind your repository .InRequestScope() and use the OnePerRequestModule which will dispose your objects at the end of the request.
This question already has answers here:
Multiple implementations for one interface with DI
(2 answers)
Closed 6 years ago.
For the following interfaces and classes, how do I use Unity Container to Fluently (programatically) wire it up so that FooController gets an instance of ARepository and BarController gets an instance of BRepository via constructor injection?
public interface IRepository
{
}
public class ARepository : IRepository
{
}
public class BRepository : ARepository
{
}
public class FooController
{
public FooController(IService service, IRepository repository)
{
}
}
public class BarController
{
public BarController(IService service, IRepository repository)
{
}
}
You can achieve this at registration time by telling each controller registration how to resolve its constructor parameters.
container.RegisterType<FooController>(new InjectionConstructor(
new ResolvedParameter<IService>(), new ResolvedParameter<ARepository>());
container.RegisterType<BarController>(new InjectionConstructor(
new ResolvedParameter<IService>(), new ResolvedParameter<BRepository>());
I would highly recommend against creating a dedicated/local/injected UnityContainer for each type like one of the posters suggested.
This can be approached in two ways.
One is by specifically defining the resolving in registration time as TylerOhlsen suggested.
This is a good solution, though if you register later both ARepository and BRepository as implementations for IRepository, you still need to deal with the fact you have two implenetations for the same interface, and if a third class will someday require an implementation of IRepository, without defining it specifically in the registration, it will get an unpredictable instance.
The second option, which is slightly safer, is registering a factory for IRepository.
The simplest example would be using a string as the key, like this:
// Create a resolver(abstract factory) for the IRepository interface type
var resolver = myContainer.Resolve<Func<IRepository>>();
// ... other code here...
// Register mappings for the IRepository interface to appropriate concrete types
myContainer.RegisterType<IRepository, ARepository>("A");
myContainer.RegisterType<IRepository, BRepository>("B");
Then in the implementation of FooController and BarController receive the func factory by injection and select the right instance.
public class FooController
{
IRepository repository;
public FooController(IService service, Func<IRepository> repositoryFactory)
{
repository = repositoryFactory("A");
}
}
You can read more about this here:
http://msdn.microsoft.com/en-us/library/ff660854%28v=pandp.20%29.aspx
You can register the type with a name and then use that in a Dependency attribute of the target classes:
// Register mappings for the IRepository interface to appropriate concrete types
myContainer.RegisterType<IRepository, ARepository>("A");
myContainer.RegisterType<IRepository, BRepository>("B");
Then in the FooController and BarController, declare which implementation you require with the Dependency attribute:
public class FooController
{
public FooController(IService service, [Dependency("A")] IRepository repository)
{
}
}
public class BarController
{
public BarController(IService service, [Dependency("B")] IRepository repository)
{
}
}
You can use a public const string in ARepository and BRepository rather than "A" and "B" in both RegisterType and Dependency.
One possibility is to register the specific type to be resolved by the UnityContainer when resolving IRepository:
IUnityContainer container = new UnityContainer();
container.RegisterType<IRepository, BRepository>(new ContainerControlledLifetimeManager());
Using this depends on whether you require finer grained control over what types are resolved in certain contexts - if you do, you might consider using a local IUnityContainer instance and using RegisterInstance() instead:
//Assumes container is instantiated and already populated with other instances/type mappings.
IUnityContainer childContainer = container.CreateChildContainer();
container.RegisterInstance<IRepository>(new BRepository(), new ContainerControlledLifetimeManager());
JoefGoldstein got me most of the way, but I got a few errors when attempting that.
I had to register my classes with a named dependency and use the InjectionFactory class to resolve the dependency.
// register interfaces to implementations with a named dependency
myContainer.RegisterType<IRepository, ARepository>("A");
myContainer.RegisterType<IRepository, BRepository>("B");
// register Injection factory to resolve the dependency
container.RegisterType<Func<string, IRepository>>(
new InjectionFactory(c =>
new Func<string, IRepository>(name => c.Resolve<IRepository>(name)))
);
Then in my controller
public class FooController
{
IRepository repository;
public FooController(IService service, Func<string, IRepository> repositoryFactory)
{
repository = repositoryFactory("A");
}
}
This is probably asked before but I can't work it out. Maybe if I could get the title right I could goolge it.
I have got this generic repository interface:
public interface IRepository<TEntity>
{
TEntity Resolve<TEntity>(); // dummy function, just to get the idea
}
I also have a generic unit of work, which is able to resolve a generic repository:
public interface IUnitOfWork
{
IRepository<TEntity> GetGenericRepository<TEntity>() where TEntity : class;
}
So far so good.
But as real life continues, I would like to create a custom repository, with some specific funtions. So I was thinking: inheritance; like this:
public class SpecialRepository : IRepository<SomeEntityType>
{
public void SomeSpecialFunction() { };
}
Obviously, this type cannot be resolved with the GetGenericRepository methode so I thought: lets add a extra method to the IUnitOfWork interface:
public interface IUnitOfWork
{
//same old get generic repository
IRepository<TEntity> GetGenericRepository<TEntity>() where TEntity : class;
//the newly added.
T GetInheretedRepository<T>() where T : class;
}
I want to be able to call the unit of work with the special repository, something like this:
public test()
{
IUnitOfWork uow = new UnitOfWork();
//I want to make this call with a constraint on TemplateRepo
//to enforce it's type: IRepository<T> (which TemplateRepo is)
var y = uow.GetInheretedRepository<TemplateRepo>();
}
The question is: how can I restrict type T in T GetInheretedRepository<T>() where T : class; to be of type: IRepository<TEntity>?
I tried this:
public interface IUnitOfWork
{
//the newly added.
//error: Only class or interface could be specified as constraint
T GetInheretedRepository<T>() where T : class, IRepository; }
and
public interface IUnitOfWork
{
//the newly added.
//error: type argument missing
T GetInheretedRepository<T>() where T : class, IRepository<>;
}
that doesnt work.
I could drop the constrain as a quick-fix or perhaps create an inherited unit of work, but then; the question still remains.
The way to do this is by adding a second generic type argument, as follows:
TRepository GetInheretedRepository<TRepository, TEntity>()
where TRepository : IRepository<TEntity>
where TEntity : class;
Here you supply both the Repository type and the entity type. This way the C# compiler can check whether or not the type matches. Here's how to call it:
var rep = uow.GetInheretedRepository<SpecialRepository, SomeEntityType>();
rep.SomeSpecialFunction();
This obviously sucks, since you will have to specify both types. But more importantly, this sucks because you have to specify the concrete type, making your code take a dependency on a concrete type; a violation of the Dependency Inversion Principle.
I really would like to advice to to step away from a design where you depend on a concrete type, or even better, step away from a design where you have many methods on a specific repository class, because this violates both SRP, OCP and ISP and this will likely cause maintenance problems later on.
So instead, take a look at the application design that is described in this article.
You need to specify second Type like
public interface IUnitOfWork
{
//the newly added.
T GetInheretedRepository<T, TEntity>() where T : class, IRepository<TEntity>;
}
public interface IRepository<TEntity>
{
TEntity Resolve(); // dummy function, just to get the idea
}
example that compiles fine - https://dotnetfiddle.net/MmmPil
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);