ASP.Net Core Open Partial Generic Dependency Injection - asp.net-core

I would like to register the following items for DI using an open generic implementation and interface. I know the following example will not work, as well as other combinations I've tried with MakeGenericType, or GetGenericArguments. I would like to simply call AddRepository<MyDbContext> and then be able to inject my implementation into classes without explicitly having to register the type I am using.
Interface
public interface IRepository<TEntity>
{
}
Implementation
public class Repository<TEntity, TContext> : IRepository<TEntity>
where TEntity : class
where TContext : DbContext
{
}
Registration
public static class RepositoryServiceCollectionExtensions
{
public static IServiceCollection AddRepository<TContext>(
this IServiceCollection services) where TContext : DbContext
{
services.TryAddScoped(
typeof(IRepository<>),
typeof(Repository< , TContext>));
return services;
}
}

The dependency injection container Microsoft.Extensions.DependencyInjection and its abstraction layer does not support open generic factories. So you generally cannot achieve what you would like to do there. There’s also no support planned.
Unlike many those other dependency injection related features, this is also not really possible to patch by just providing the right wrapper or factory types. So you will actually have to change your design here.
Since you want to resolve IRepository<TEntity> and the only way to do this is by registering an equivalent open generic type, you will have to have some type Repository<TEntity> that implements your repository. That makes it impossible to retrieve the database context type from the generic type argument, so you will have to use a different way here.
You have different options to do that. For example, you could configure your Repository<TEntity> (e.g. using M.E.Options) with the context type and make that resolve the Repository<TEntity, TContext> dynamically. But since you have actual control over your database context, I would suggest either adding a marker interface or introducing another type for the context which you can then register with the container:
public class Repository<TEntity> : IRepository<TEntity>
{
public Repository(IDbContext dbContextFactory)
{ … }
}
public class MyDbContext : DbContext, IDbContext
{ … }
Then, your extension method could look like this:
public static IServiceCollection AddRepository<TContext>(this IServiceCollection services)
where TContext : DbContext, IDbContext
{
services.AddTransient(typeof(IDbContext), sp => sp.GetService<TContext>());
services.TryAddScoped(typeof(IRepository<>), typeof(Repository<>));
return services;
}
Of course, this changes how your Repository implementation works, but I don’t actually assume that you need to know the TContext type other than to inject the database context type. So this will probably still work for you.
That being said, I have too agree with Chris Pratt, that you probably don’t need this. You say that you want to introduce the repository, because “coding stores and implementations for every entity is a time consuming task” but you should really think about whether you actually need that. A generic repository is very limited in what it can do, and mostly means that you are doing just CRUD operations. But exactly that is what DbContext and DbSet<T> already do:
C: DbContext.Add, DbSet<T>.Add
R: DbContext.Find, DbSet<T>.Find
U: DbContext.Update, DbSet<T>.Update
D: DbContext.Remove, DbSet<T>.Remove
In addition, DbContext is a “unit of work” and DbSet<T> is an IQueryable<T> which gives you a lot more control and power than a generic repository could possible give you.

You cannot have a partially open generic reference. It's all or nothing. In other words, you can try:
services.TryAddScoped(
typeof(IRepository<>),
typeof(Repository<,>));
But, if that doesn't work, you'll likely need to add a type param to your AddRepository method:
public static IServiceCollection AddRepository<TEntity, TContext>(this IServiceCollection services)
where TEntity : class
where TContext : DbContext
{
services.TryAddScoped(
typeof(IRepository<TEntity>),
typeof(Repository<TEntity, TContext>));
return services;
}
Of course, I think that breaks what you're ultimately trying to achieve here: registering repositories for all the entity types in one go. You can always use a bit of reflection find all entities in your assembly (they would need to share something in common: base class, interface, etc.) and then enumerate over them and use reflection to call AddScoped on your service collection for each.
All that said, the best thing you can do here is to actually throw all this away. You don't need the repositories. EF already implements the repository and unit of work patterns. When you use an ORM like EF, you're essentially making that your data layer instead of a custom class library you create. Putting you own custom wrapper around EF not only adds entropy to your code (more to maintain, more to test, and more than can break), but it can also mess up the way EF works in many cases, leading to less efficiency in the best cases and outright introducing bugs into your application in the worst cases.

Related

What is the best approache to share a UnitOfWork between two Repositories using Unity?

I want to use Unity as an IoC besides the UnitOfWork and Repository patterns. I read various related articles and questions but none of them satisfied me completely.
I have a problem with all approaches. An example would explain better my problem:
We want to work with two repositories at two separate classes (maybe the business services) but the overall works are in a unit.
Start point is the LocalService1.Method1 method.
public class LocalService1
{
public void Method1(int id)
{
var repository1 = Container.Current.Resolve<IRepository1>(); // Injects the IUnitOfWork for the repository.
var entity1 = repository1.GetEntity1(id);
var service2 = Container.Current.Resolve<LocalService2>(); // Maybe it’s better not to use IoC for business logic. This is not my issue.
service2.Method2(entity1)
}
}
...
public class LocalService2
{
public void Method2(Entity1 entity1)
{
var repository2 = Container.Current.Resolve<IRepository2>(); // Injects the IUnitOfWork for the repository.
var count = repository2.GetEntity2sCount(entity1.Id);
// Do some works with count and entity1
}
}
The main question is that “How can I share the UnitOfWork (here can be ObjectContext) between the IRepository1 and IRepsitory2 while calling the LocalService1.Method1?”.
More important thing is that “I want to be sure about UnitOfWork disposal”.
I guess the answers would focus on these issues:
IoC configuration
Life Time configuration
Disposal time (How and when?)
If you recommend using “HttpContext” please consider about non-web environments.
I know my question is almost about the “Life time management” but I’m looking for an exhaustive approach.
First: Don't use Unity as a ServiceLocator. This is considered an anti-pattern. Use constructor injection instead.
Unity's LifetimeManagers don't clean up after themselves. This feature is on the wish list for Unity vNext.
If you want your objects to be disposed you should create your own LifetimeManager and a related BuilderStrategy that do clean up.
There is a sample in the TecX project (inside TecX.Unity.Lifetime) which is taken from Mark Seemann's book Dependency Injection in .NET.

What do you mean by "programming to interface" and "programming to implementation"?

In the Head First Design Patterns book, the author often says that one should program to interface rather than implementation?
What does that mean?
Let's illustrate it with the following code:
namespace ExperimentConsoleApp
{
class Program
{
static void Main()
{
ILogger loggerA = new DatabaseLogger();
ILogger loggerB = new FileLogger();
loggerA.Log("My message");
loggerB.Log("My message");
}
}
public interface ILogger
{
void Log(string message);
}
public class DatabaseLogger : ILogger
{
public void Log(string message)
{
// Log to database
}
}
public class FileLogger : ILogger
{
public void Log(string message)
{
// Log to File
}
}
}
Suppose you are the Logger developer and the application developer needs a Logger from you. You give the Application developer your ILogger interface and you say to him he can use but he doesn't have to worry about the implementation details.
After that you start developing a FileLogger and Databaselogger and you make sure they follow the interface that you gave to the Application developer.
The Application developer is now developing against an interface, not an implementation. He doesn't know or care how the class is implemented. He only knows the interface. This promotes less coupling in code and it gives you the ability to (trough configuration files for example) easily switch to another implementation.
Worry more about what a class does rather than how it does it. The latter should be an implementation detail, encapsulated away from clients of your class.
If you start with an interface, you're free to inject in a new implementation later without affecting clients. They only use references of the interface type.
It means that when working with a class, you should only program against the public interface and not make assumptions about how it was implemented, as it may change.
Normally this translates to using interfaces/abstract classes as variable types instead of concrete ones, allowing one to swap implementations if needed.
In the .NET world one example is the use of the IEnumerable/IEnumerator interfaces - these allow you to iterate over a collection without worrying how the collection was implemented.
It is all about coupling. Low coupling is a very important property* of software architecture. The less you need to know about your dependency the better.
Coupling can be measured by the number of assumptions you have to make in order to interact/use your dependency (paraphrasing M Fowler here).
So when using more generic types we are more loosely coupled. We are for example de-coupled from a particular implementation strategy of a collection: linked list, double linked list, arrays, trees, etc. Or from the classic OO school: "what exact shape it is: rectangle, circle, triangle", when we just want to dependent on a shape (in old school OO we apply polymorphism here)

Interface reference variables

I am going over some OO basics and trying to understand why is there a use of Interface reference variables.
When I create an interface:
public interface IWorker
{
int HoneySum { get; }
void getHoney();
}
and have a class implement it:
public class Worker : Bee, IWorker
{
int honeySum = 15;
public int HoneySum { get { return honeySum; } }
public void getHoney()
{
Console.WriteLine("Worker Bee: I have this much honey: {0}", HoneySum);
}
}
why do people use:
IWorker worker = new Worker();
worker.getHoney();
instead of just using:
Worker worker3 = new Worker();
worker3.getHoney();
whats the point of a interface reference variable when you can just instatiate the class and use it's methods and fields that way?
If your code knows what class will be used, you are right, there is no point in having an interface type variable. Just like in your example. That code knows that the class that will be instantiated is Worker, because that code won't magically change and instantiate anything else than Worker. In that sense, your code is coupled with the definition and use of Worker.
But you might want to write some code that works without knowing the class type. Take for example the following method:
public void stopWorker(IWorker worker) {
worker.stop(); // Assuming IWorker has a stop() method
}
That method doesn't care about the specific class. It would handle anything that implements IWorker.
That is code you don't have to change if you want later to use a different IWorker implementation.
It's all about low coupling between your pieces of code. It's all about maintainability.
Basically it's considered good programming practice to use the interface as the type. This allows different implementations of the interface to be used without effecting the code. I.e. if the object being assigned was passed in then you can pass in anything that implements the interface without effecting the class. However if you use the concrete class then you can only passin objects of that type.
There is a programming principle I cannot remember the name of at this time that applies to this.
You want to keep it as generic as possible without tying to specific implementation.
Interfaces are used to achieve loose coupling between system components. You're not restricting your system to the specific concrete IWorker instance. Instead, you're allowing the consumer to specify which concrete implementation of IWorker they'd like to use. What you get out of it is loosely dependent components and better flexibility.
One major reason is to provide compatibility with existing code. If you have existing code that knows how to manipulate objects via some particular interface, you can instantly make your new code compatible with that existing code by implementing that interface.
This kind of capability becomes particularly important for long-term maintenance. You already have an existing framework, and you typically want to minimize changes to other code to fit your new code into the framework. At least in the ideal case, you do this by writing your new code to implement some number of existing interfaces. As soon as you do, the existing code that knows how to manipulate objects via those interfaces can automatically work with your new class just as well as it could with the ones for which it was originally designed.
Think about interfaces as protocols and not classes i.e. does this object implement this protocol as distinct from being a protocol? For example can my number object be serialisable? Its class is a number but it might implement an interface that describes generally how it can be serialised.
A given class of object may actually implement many interfaces.

How to set NHibernate Linq fetch strategy through a façade layer

I’m using NHibernate for data access, but accessing it through a façade layer. This layer consists of interfaces for the repositories, plus an IUnitOfWork interface which corresponds to the ISession object.
In order that retrieved entities are managed correctly, repositories are passed an IUnitOfWork in their constructor and the IUnitOfWork is used for the loading.
The IUnitOfWork contains a property called All, which retrieves all entities of the class as an IQueryable (for later filtering). Thus, a repository method to retrieve all entities created this year might look like the following:
NB: this is not the complete code for these interfaces and classes! Only the code relevant to my question.
IUnitOfWork interface:
IQueryable<T> GetList<T>();
UnitOfWork concrete class:
public IQueryable<T> GetList<T>()
{
return _session.Linq<T>();
}
IFooRepository interface
IQueryable<Foo> All { get; }
IEnumerable<Foo> ThisYearsFoos{ get; }
FooRepository concrete class
public IQueryable<Foo> All
{
get { return _unitOfWork.GetList<Foo>(); }
}
public IEnumerable<Foo> ThisYearsFoos
{
get { return All.Where(x => x.DateCreated > new DateTime(2010,1,1);}
}
I would like to add functionality to specify fetch strategies so that related entities can be eagerly loaded. So let’s say Foo has a property corresponding to another entity, Bar:
public class Foo
{
public Bar {get;set;}
}
The mapping file specifies that Bar is lazy-loaded, but in my ThisYearsFoos repository property I would like to specify that Bar should be eagerly loaded to avoid N+1 selects.
In Linq to NHibernate we can specify eager fetching using the Expand() extension method. However, this extension method belongs to the NHibernateQueryable type, whereas the IUnitOfWork interface’s GetList method only knows about IQueryable.
Clearly I don’t want the IUnitOfWork interface to know about INHibernateQueryable since it is supposed to not know about NHibernate.
Using the design I have specified above, is there a way to do this that I haven’t been able to think of? Or is my design in need of a rethink?
Thanks
David
Upgrade to NHibernate 3.x. The new method that corresponds to Expand (Fetch) operates on IQueryable.
You are saying some conflicting things:
- You don't want to expose interface
- You want to use the use that interface
That is impossible. You have to rethink your design.
You use the term unit of work for a different thing than most people do.
Most people would expect a unit of work interface to have the methods Commit and RollBack, but not some IQueryable.

Repository pattern with Entity Frameworks 4

I used to use NHibernate with repository interfaces.
What is the proper way to use this pattern with EF?
How can I implement this repository interface, for a RepositoryBase<T>?
public interface IRepository<T>
{
T GetById(object id);
void Save(T entity);
T[] GetAll();
void Delete(T entity);
}
For some reason all of the examples given expose the collections as IQueryable or IEnumerable. EF4 has an interface for this very purpose - IObjectSet (or IDbSet if you're using the latest CTP).
Julie Lerman has a tremendous post on doing this, including creating a MockSet that implements IObjectSet, so you can do some disconnected unit testing
http://thedatafarm.com/blog/data-access/agile-entity-framework-4-repository-part-6-mocks-amp-unit-tests/
It's not really a whole lot different than any other ORM. Here's an example: http://blogs.microsoft.co.il/blogs/gilf/archive/2010/01/20/using-repository-pattern-with-entity-framework.aspx
Have a look at the Entity Framework Repository & Unit of Work Template. You have some details here.
There are several approaches (most of them are quite similar and only differ slightly), so I would recommend doing some research and choosing which one suits you best.
With EF 4 it is possible to implement a generic repository by using ObjectSet<T>. Take a look at a few articles that might help:
http://devtalk.dk/2009/06/09/Entity+Framework+40+Beta+1+POCO+ObjectSet+Repository+And+UnitOfWork.aspx
http://www.forkcan.com/viewcode/166/Generic-Entity-Framework-40-Base-Repository
You basically have your Repositories talk yo your object context. Only change I would make would be having your GetAll return an IEnumerable instead something like:
public class SomeObjectRepo : IRepository<SomeObject>
{
SomeContext GetById(object id)
{
using(var context = new MyContext())
{
return context.SomeObjects.First(x=>x.id.Equals(id));
}
}
etc...
}
This is my solution: http://www.necronet.org/archive/2010/04/10/generic-repository-for-entity-framework.aspx
I like this because it doesn't couple instance of repository with specific instance of object context, so with some DI framework, I can have all my repositories be singletons.