Architectural decision regarding Repository pattern (it is using Automapper) - entity-framework

I have:
Domain models (Model)
Database entities (Entity)
Repository: that accepts the model and converts it to the database entity (using automapper) and saves it to the database. In some cases returns back a Model object.
Example:
public class BaseRepository<T, U> : IRepository<T, U>
{
public void Insert(T model)
{
U entity= Mapper.Map<T, U>(model);
dbContext.Set<U>().Add(entity);
dbContext.SaveChanges();
}
}
Now when creating repository objects from a business layer i would instantiate the repository as:
new BaseRepository<Model, Entity>()
PROBLEM
Now this requires that the business layer have access to both the model and database entity projects. I want to avoid the reference of database entity to the business layer. My business layer should be able to instantiate repositories using only the domain model.
new BaseRepository<Model>()
for which i need a repository as
public class BaseRepository<T> : IRepository<T>
But then i cant find a way to handle the mapping between model and entity(automapper).
Is what i am asking valid? OR is my requirement absurd?
Note: I think my business layer should not have a reference to database entities because i do not want anyone using database entities directly. They should be working only with the model classes.

So the answer is simple. Bit of a silly question to begin with. The declaration for IRep was wrong.
BaseRep<T,U>:IRep<T> instead of IRep<T, U>.
The rep interface should be:
public interface IRepository<T>
where T : class
{
void Insert(T model);
IEnumerable<T> GetAll();
}
The base repository should be:
public class BaseRepository<T, U> : IRepository<T>
where T : class
where U : class
{
protected readonly IPARS_ADOEntities dbContext;
public BaseRepository()
: this(new IPARS_ADOEntities())
{
}
public BaseRepository(IPARS_ADOEntities dbContext)
{
this.dbContext = dbContext;
}
public void Insert(T model)
{
U entity = Mapper.Map<T, U>(model);
dbContext.Set<U>().Add(entity);
dbContext.SaveChanges();
}
public IEnumerable<T> GetAll()
{
IEnumerable<U> entities = dbContext.Set<U>();
return Mapper.Map<IEnumerable<U>, IEnumerable<T>>(entities);
}
}
In the business layer:
public class BizLayer
{
public List<EmployeeModel> GetEmployee(IRepository<EmployeeModel> rep)
{
return rep.GetAll();
}
}
From the presentation or application root you inject the dependency:
bizlayer.GetEmployees(new IRepository<EmployeeModel, EmployeeEntity>())

Related

Creating Repository Pattern that provides multiple DbContexts with Entity Framework in .Net Core Web API

I want to develop a structure that will support generic DbContexts in the .Net Core Web API project and can be used in the repository pattern. Mysql and PostreSql databases are sufficient for now. Can you help with this?
Create a new .Net Core Web API project.
Add a new folder in the project called DataAccess and create a new class called BaseDbContext that inherits from DbContext. This class will contain the common properties and methods for all your DbContexts.
public class BaseDbContext : DbContext
{
public BaseDbContext(DbContextOptions options) : base(options) { }
//...
}
Create a new class called MySqlDbContext that inherits from BaseDbContext. This class will contain the properties and methods specific to the MySQL database.
public class MySqlDbContext : BaseDbContext
{
public MySqlDbContext(DbContextOptions<MySqlDbContext> options) : base(options) { }
//...
}
Create a new class called PostgreSqlDbContext that inherits from BaseDbContext. This class will contain the properties and methods specific to the PostgreSQL database.
public class PostgreSqlDbContext : BaseDbContext
{
public PostgreSqlDbContext(DbContextOptions<PostgreSqlDbContext> options) :
base(options) { }
//...
}
Create a new folder in the project called Repositories and create a new class called BaseRepository that will contain the common methods for all your repositories.
public class BaseRepository<T> where T : class
{
protected readonly DbContext _context;
public BaseRepository(DbContext context)
{
_context = context;
}
//...
}
Create new classes for each repository that inherits from BaseRepository and pass the appropriate DbContext to the base constructor.
public class MySqlRepository : BaseRepository<MySqlDbContext>
{
public MySqlRepository(MySqlDbContext context) : base(context) { }
//...
}
and
public class PostgreSqlRepository : BaseRepository<PostgreSqlDbContext>
{
public PostgreSqlRepository(PostgreSqlDbContext context) : base(context) { }
//...
}
In your controllers you can now inject the appropriate repository and use it to interact with the database.
You can also use dependency injection to inject the appropriate DbContext based on the configuration.
Additional:
Here is an example of how you can do this:
In your appsettings.json file, add a section for the database connection information, such as:
{
"ConnectionStrings": {
"MySqlConnection": "Server=localhost;Database=mydb;User=user;Password=password;",
"PostgreSqlConnection": "Host=localhost;Database=mydb;Username=user;Password=password;"
},
"DatabaseProvider": "MySql"
}
Here the DatabaseProvider field indicate the database that user wants to use.
2. In your Startup.cs file, create a new method called ConfigureDbContext that will configure the DbContext based on the configuration in the appsettings file
public void ConfigureDbContext(IServiceCollection services)
{
var connectionString = Configuration.GetConnectionString("MySqlConnection");
var provider = Configuration.GetValue<string>("DatabaseProvider");
if(provider == "MySql")
{
services.AddDbContext<MySqlDbContext>(options => options.UseMySql(connectionString));
}
else if (provider == "PostgreSql")
{
services.AddDbContext<PostgreSqlDbContext>(options => options.UseNpgsql(connectionString));
}
}
In the ConfigureServices method in Startup.cs, call the ConfigureDbContext method to configure the DbContext.
public void ConfigureServices(IServiceCollection services)
{
ConfigureDbContext(services);
//...
}
In your controllers, you can now inject the appropriate DbContext using dependency injection.
public class MyController : Controller
{
private readonly IDbContext _context;
public MyController(IDbContext context)
{
_context = context;
}
//...
}

Using Dependency Injection with Breezejs

I am building an EntityFramework/WebApi back end.
I want to decouple my WebApi from the Entity Framework, and utilize Dependency Injection so I can swap out the "data source" for the web API.
I have been looking at the Unit of Work and Repository patterns.
I also want to use breezejs.
The breezejs TempHire samples has been alot of help, so I will use this as an example for my question -
https://github.com/Breeze/breeze.js.samples/tree/master/net/TempHire
In this sample, on the data side we have the UnitOfWork class -
public class UnitOfWork
{
private readonly EFContextProvider<TempHireDbContext> _contextProvider;
public UnitOfWork()
{
_contextProvider = new EFContextProvider<TempHireDbContext>();
StaffingResources = new Repository<StaffingResource>(_contextProvider.Context);
Addresses = new Repository<Address>(_contextProvider.Context);
// .. etc.
}
public IRepository<StaffingResource> StaffingResources { get; private set; }
public IRepository<Address> Addresses { get; private set; }
// .. etc.
public SaveResult Commit(JObject changeSet)
{
return _contextProvider.SaveChanges(changeSet);
}
}
Then on the WebApi side, it uses it like this -
[BreezeController]
[Authorize]
public class ResourceMgtController : ApiController
{
private readonly UnitOfWork _unitOfWork = new UnitOfWork();
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle)
{
return _unitOfWork.Commit(saveBundle);
}
// ... etc.
}
I would like to refactor to something like this, so that I could swap out the back end.
public class UnitOfWork : IUnitOfWork
public class ResourceMgtController : ApiController
{
private readonly IUnitOfWork _unitOfWork;
public ResourceMgtController(IUnitOfWork unitOfWork) {
this._unitOfWOrk = unitOfWork; // Dependency Injected...
}
// ... etc.
}
What I can't wrap my head around, is how I can make it generic. The breeze client needs a method like this -
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle)
{
return _unitOfWork.Commit(saveBundle);
}
And I can't put this in IUnitOfWork -
SaveResult SaveChanges(JObject saveBundle)
And really keep it decoupled from breeze, be able to swap out the back end for another backend. Am I attempting the abstraction at the wrong point? I guess if I want breeze on the client I will need to couple it on the backend?
You clearly can define an interface with that method:
public interface IUnitOfWork {
...
SaveResult SaveChanges(JObject saveBundle); // no problem
}
I suspect that you are objecting to the fact that both SaveResult and JObject are classes defined by libraries (Breeze.ContextProvider and Newtonsoft.Json.Linq respectively) you'd rather not reference somewhere.
These references wouldn't bother me any more than I mind referencing System.Linq to get IQueryable. In fact, a test double of SaveResult (a public class of Breeze.ContextProvider) is trivially easy to construct. Here is its definition (and the definition of KeyMapping, its only non-native dependent type):
public class SaveResult
{
public List<object> Entities;
public List<KeyMapping> KeyMappings;
public List<object> Errors;
}
public class KeyMapping
{
public string EntityTypeName;
public object TempValue;
public object RealValue;
}
But if Breeze and Newtonsoft.Json references are that noxious to you and you're willing to surrender some type safety, you can always create the interface like this:
public interface IUnitOfWork {
...
object SaveChanges(object saveBundle); // no safety, no problem
}
Then in your concrete UnitOfWork you add a suitable overload:
public object IUnitOfWork.SaveChanges(object saveBundle)
{
return SaveChanges((JObject) saveBundle);
}
public SaveResult SaveChanges(JObject saveBundle)
{
return _contextProvider.SaveChanges(saveBundle);
}
... and Bob's your uncle.
Yes, I did try it (in DocCode); worked fine for me.

Add model to table using generics

I'm trying to make a base class for crud ops but can't quite figure out how to get this part wired up or if it's possible. I'm using an EDMX w/ generated dbcontexts and pocos, so, ideally, I'd like to create a base class from where I can derive all my crud methods.
Interface:
public interface IGenericCrud<T> where T : class
{
void Add(T entity);
}
Implementation:
public abstract class MyImplementation : IGenericCrud<KnownModel>
{
protected myEntities context;
public MyImplementation()
{
context = new myEntities();
}
void Add(KnownModel entity)
{
// This doesn't work, but it's what I'd like to accomplish
// I'd like to know if this possible without using ObjectContexts
context.KnownModel(add entity);
}
}
I believe you should look into the repository pattern. That seems to be what you are looking for.

Injecting DbContext into Repository class library

The projects in my solution are set up like this:
App.Data
App.Models
App.Web
In App.Data, I'm using Entity Framework to access my data with a bunch of Repositories to abstract interaction with it. For obvious reasons, I would like my App.Web to reference only the App.Data project and not Entity Framework.
I'm using Constructor Injection to give my Controllers a reference to a Repository container that looks like this:
public interface IDataRepository
{
IUserRepository User { get; set; }
IProductRepository Product { get; set; }
// ...
}
public class DataRepository : IDataRepository
{
private readonly AppContext _context;
public DataRepository(AppContext context)
{
_context = context;
}
// ...
}
DataRepository will have a AppContext object (which inherits from Entity Framework's DbContext) that all the child Repositories will use to access the database.
So finally we come to my problem: how do I use Constructor Injection on DataRepository considering it's a code library and has no entry-point? I can't bootstrap AppContext in App.Web because then I have to reference Entity Framework from that project.
Or am I just doing something stupid?
You can define a RepositoryConnection class in App.Data that acts as a wrapper to the Context and removes the need to reference EF in App.Web. If you are using an IoC Container you can control the lifetime of the RepositoryConnection class to ensure that all instances of Repository get the same Context. This is a simplified example ...
public class RepositoryConnection
{
private readonly AppContext _context;
public RepositoryConnection()
{
_context = new AppContext();
}
public AppContext AppContext { get { return _context; } }
}
public class DataRepository : IDataRepository
{
private readonly AppContext _context;
public DataRepository(RepositoryConnection connection)
{
_context = connection.AppContext;
}
// ...
}

How to dispose resources with dependency injection

I'm using StructureMap to resolve references to my repository class. My repository interface implements IDisposable, e.g.
public interface IMyRepository : IDisposable
{
SomeClass GetById(int id);
}
An implementation of the interface using Entity Framework:
public MyRepository : IMyRepository
{
private MyDbContext _dbContext;
public MyDbContext()
{
_dbContext = new MyDbContext();
}
public SomeClass GetById(int id)
{
var query = from x in _dbContext
where x.Id = id
select x;
return x.FirstOrDefault();
}
public void Dispose()
{
_dbContext.Dispose();
}
}
Anyway as mentioned I'm using StructureMap to resolve IMyRepository. So when, where and how should I call my dispose method?
WARNING: please note that my views have changed, and you should consider the following advise outdated. Please see this answer for an updated view: https://stackoverflow.com/a/30287923/264697
While DI frameworks can manage lifetime of objects for you and some could even dispose objects for you after you're done using with them, it makes object disposal just too implicit. The IDisposable interface is created because there was the need of deterministic clean-up of resources. Therefore, in the context of DI, I personally like to make this clean-up very explicit. When you make it explicit, you've got basically two options: 1. Configure the DI to return transient objects and dispose these objects yourself. 2. Configure a factory and instruct the factory to create new instances.
I favor the second approach over the first, because especially when doing Dependency Injection, your code isn't as clean as it could be. Look for instance at this code:
public sealed class Client : IDisposable
{
private readonly IDependency dependency;
public Client(IDependency dependency)
{
this. dependency = dependency;
}
public void Do()
{
this.dependency.DoSomething();
}
public Dispose()
{
this.dependency.Dispose();
}
}
While this code explicitly disposes the dependency, it could raise some eyebrows to readers, because resources should normally only be disposed by the owner of the resource. Apparently, the Client became the owner of the resource, when it was injected.
Because of this, I favor the use of a factory. Look for instance at this example:
public sealed class Client
{
private readonly IDependencyFactory factory;
public Client(IDependencyFactory factory)
{
this.factory = factory;
}
public void Do()
{
using (var dependency = this.factory.CreateNew())
{
dependency.DoSomething();
}
}
}
This example has the exact same behavior as the previous example, but see how the Client class doesn't have to implement IDisposable anymore, because it creates and disposes the resource within the Do method.
Injecting a factory is the most explicit way (the path of least surprise) to do this. That's why I prefer this style. Downside of this is that you often need to define more classes (for your factories), but I personally don't mind.
RPM1984 asked for a more concrete example.
I would not have the repository implement IDisposable, but have a Unit of Work that implements IDisposable, controls/contains repositories and have a factory that knows how to create new unit of works. With that in mind, the above code would look like this:
public sealed class Client
{
private readonly INorthwindUnitOfWorkFactory factory;
public Client(INorthwindUnitOfWorkFactory factory)
{
this.factory = factory;
}
public void Do()
{
using (NorthwindUnitOfWork db =
this.factory.CreateNew())
{
// 'Customers' is a repository.
var customer = db.Customers.GetById(1);
customer.Name = ".NET Junkie";
db.SubmitChanges();
}
}
}
In the design I use, and have described here, I use a concrete NorthwindUnitOfWork class that wraps an IDataMapper that is the gateway to the underlying LINQ provider (such as LINQ to SQL or Entity Framework). In sumary, the design is as follows:
An INorthwindUnitOfWorkFactory is injected in a client.
The particular implementation of that factory creates a concrete NorthwindUnitOfWork class and injects a O/RM specific IDataMapper class into it.
The NorthwindUnitOfWork is in fact a type-safe wrapper around the IDataMapper and the NorthwindUnitOfWork requests the IDataMapper for repositories and forwards requests to submit changes and dispose to the mapper.
The IDataMapper returns Repository<T> classes and a repository implements IQueryable<T> to allow the client to use LINQ over the repository.
The specific implementation of the IDataMapper holds a reference to the O/RM specific unit of work (for instance EF's ObjectContext). For that reason the IDataMapper must implement IDisposable.
This results in the following design:
public interface INorthwindUnitOfWorkFactory
{
NorthwindUnitOfWork CreateNew();
}
public interface IDataMapper : IDisposable
{
Repository<T> GetRepository<T>() where T : class;
void Save();
}
public abstract class Repository<T> : IQueryable<T>
where T : class
{
private readonly IQueryable<T> query;
protected Repository(IQueryable<T> query)
{
this.query = query;
}
public abstract void InsertOnSubmit(T entity);
public abstract void DeleteOnSubmit(T entity);
// IQueryable<T> members omitted.
}
The NorthwindUnitOfWork is a concrete class that contains properties to specific repositories, such as Customers, Orders, etc:
public sealed class NorthwindUnitOfWork : IDisposable
{
private readonly IDataMapper mapper;
public NorthwindUnitOfWork(IDataMapper mapper)
{
this.mapper = mapper;
}
// Repository properties here:
public Repository<Customer> Customers
{
get { return this.mapper.GetRepository<Customer>(); }
}
public void Dispose()
{
this.mapper.Dispose();
}
}
What's left is an concrete implementation of the INorthwindUnitOfWorkFactory and a concrete implementation of the IDataMapper. Here's one for Entity Framework:
public class EntityFrameworkNorthwindUnitOfWorkFactory
: INorthwindUnitOfWorkFactory
{
public NorthwindUnitOfWork CreateNew()
{
var db = new ObjectContext("name=NorthwindEntities");
db.DefaultContainerName = "NorthwindEntities";
var mapper = new EntityFrameworkDataMapper(db);
return new NorthwindUnitOfWork(mapper);
}
}
And the EntityFrameworkDataMapper:
public sealed class EntityFrameworkDataMapper : IDataMapper
{
private readonly ObjectContext context;
public EntityFrameworkDataMapper(ObjectContext context)
{
this.context = context;
}
public void Save()
{
this.context.SaveChanges();
}
public void Dispose()
{
this.context.Dispose();
}
public Repository<T> GetRepository<T>() where T : class
{
string setName = this.GetEntitySetName<T>();
var query = this.context.CreateQuery<T>(setName);
return new EntityRepository<T>(query, setName);
}
private string GetEntitySetName<T>()
{
EntityContainer container =
this.context.MetadataWorkspace.GetEntityContainer(
this.context.DefaultContainerName, DataSpace.CSpace);
return (
from item in container.BaseEntitySets
where item.ElementType.Name == typeof(T).Name
select item.Name).First();
}
private sealed class EntityRepository<T>
: Repository<T> where T : class
{
private readonly ObjectQuery<T> query;
private readonly string entitySetName;
public EntityRepository(ObjectQuery<T> query,
string entitySetName) : base(query)
{
this.query = query;
this.entitySetName = entitySetName;
}
public override void InsertOnSubmit(T entity)
{
this.query.Context.AddObject(entitySetName, entity);
}
public override void DeleteOnSubmit(T entity)
{
this.query.Context.DeleteObject(entity);
}
}
}
You can find more information about this model here.
UPDATE December 2012
This an an update written two years after my original answer. The last two years much has changed in the way I try to design the systems I'm working on. Although it has suited me in the past, I don't like to use the factory approach anymore when dealing with the Unit of Work pattern. Instead I simply inject a Unit of Work instance into consumers directly. Whether this design is feasibly for you however, depends a lot on the way your system is designed. If you want to read more about this, please take a look at this newer Stackoverflow answer of mine: One DbContext per web request…why?
If you want to get it right, i'd advise on a couple of changes:
1 - Don't have private instances of the data context in the repository. If your working with multiple repositories then you'll end up with multiple contexts.
2 - To solve the above - wrap the context in a Unit of Work. Pass the unit of work to the Repositories via the ctor: public MyRepository(IUnitOfWork uow)
3 - Make the Unit of Work implement IDisposable. The Unit of Work should be "newed up" when a request begins, and therefore should be disposed when the request finishes. The Repository should not implement IDisposable, as it is not directly working with resources - it is simply mitigating them. The DataContext / Unit of Work should implement IDispoable.
4 - Assuming you are using a web application, you do not need to explicitly call dispose - i repeat, you do not need to explicitly call your dispose method. StructureMap has a method called HttpContextBuildPolicy.DisposeAndClearAll();. What this does is invoke the "Dispose" method on any HTTP-scoped objects that implement IDisposable. Stick this call in Application_EndRequest (Global.asax). Also - i believe there is an updated method, called ReleaseAllHttpScopedObjects or something - can't remember the name.
Instead of adding Dispose to IMyRepository, you could declare IMyRepository like this:
public interface IMyRepository: IDisposable
{
SomeClass GetById(int id);
}
This way, you ensure all repository will call Dispose sometimes, and you can use the C# "using" pattern on a Repository object:
using (IMyRepository rep = GetMyRepository(...))
{
... do some work with rep
}