I have a multi tier web application working on ASP.NET MVC 5.
I have completely separated Infrastructure (DAL) from UI using a business layer.
any time UI function needs a DAL access, it calls my business service and the business service does it's job and if needed returns a result.
For IoC, Business services are injected into UI project and Infrastructure injected into Business service using Ninject
I need my UI project to have exactly 0 reference to my infrastructure project, but when it comes to using ASP.NET Identity 2 framework, It needs reference to infrastructure for ApplicationDbContext.
There are two reference to my Infrastructure project one from IdentityConfig.cs in
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
and another from Startup.Auth.cs in
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
what is the solution for this?
This is the schema of the Architecture I used:
Interfaces and factory methods will solve your problem. Whenever you want to create object - use simple factory that returns an interface of your object. And whenever you want to abstract from concrete implementation - use interfaces.
public class ApplicationDbContextFactory
{
public static IApplicationDbContext Create(IOwinContext owinContext)
{
return ApplicationDbContext.Create(owinContext);
}
}
With big thanks to #Andrei M for his great help and guidance,
I Solved this as below:
First Step: I Created An IDbContext Interface in my Domain Layer. (because from presentation we don't have access to my Infrastructure Layer)
public interface IDbContext : IDisposable
{
}
Second Step: Implement IDbContext Interface in my ApplicationDbContext in Infrastructure Layer.
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>, IDbContext
Third Step: As In my Project, the only layer that has reference to my Infrastructure Layer, is Business layer. so for use my ApplicationDbContext in my owin startup class in presentation layer, I need a Factory class in my business layer to return me a Db Context.
public static class DbContextFactory
{
public static IDbContext Create()
{
return new ApplicationDbContext();
}
}
Forth Step: Changing the Owin Startup class to use My DbContextFactory Class whenever it needs a DbContext.
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context, user manager and signin manager to use a single instance per request
app.CreatePerOwinContext(DbContextFactory.Create);
Final Step: the only thing that remains is to change IdentityConfig.cs to don't reference directly to ApplicationDbContext in it's create method.
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var myUserStore = new UserStore<ApplicationUser>((IdentityDbContext<ApplicationUser>) context.Get<IDbContext>());
var manager = new ApplicationUserManager(myUserStore);
Actually for this step I have two solution, first is what you see above (Cast to IdentityDbContext<ApplicationUser>)
second is Cast to DbContext. I Don't know if I'll have any problem with casting to DbContext (in System.Data.Entity namespace) later, and for now I use the first solution for this.
Related
I am developing a web API in .NET Core with multiple DataContexts(DbContext). I have used repository pattern to handle DB calls. The Repository class accepts a DbContext as a generic type.
public class Repository<T> : IRepository where T : DbContext
{
public Repository(T context) : base(context)
{
}
}
This Repository class injects to service classes as IRepository from the Startup. I want to connect with 2 databases. So I`m using 2 DataContext classes and passed them in to repository class in the startup.
Here is my Startup class,
services.AddTransient<DataContext1>(x => new DataContext1(Configuration.GetConnectionString("Database1")));
services.AddTransient<IRepository, Repository<DataContext1>>();
services.AddTransient<DataContext2>(x => new DataContext2(Configuration.GetConnectionString("Database2")));
services.AddTransient<IRepository, Repository<DataContext2>>();
When I request IRepository it always injects the Repository class with the last DataContext(DataContext2). What is the best way to solve this problem without affecting to the API performance(Memory / CPU).
Here is my Service class,
private readonly IRepository _repository;
public BookService(IRepository repository)
{
_repository = repository;
}
I think you should at least create one repository interface for each type of database in order of the dependency injection system can handle it.
Inject a factory class for the repositories instead of an instance of the repositories themselves. Implement the factory methods to suit your needs.
im making a project with a persistence layer, domain layer, and business layer, i implementing the generic repository pattern and unit of work with entity framework core.
I want to use this project in a web api rest and in a UWP project.
The correct ways its override the method?, add the context in the startup configureservices? When dispose a dbcontext?
Read documentation on configuring DbContext: https://learn.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext
Basically, you add it to your services:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<BloggingContext>(options => options.UseSqlite("Data Source=blog.db"));
}
Then you inject it into whatever class you want. An easy example would be inejecting it into a Controller (but you could inject into any class that is added to your services):
public class MyController
{
private readonly BloggingContext _context;
public MyController(BloggingContext context)
{
_context = context;
}
...
}
The Dependency Injection library will then handle disposal - you do not call Dispose directly. This is described in documentation here.
The framework takes on the responsibility of creating an instance of
the dependency and disposing of it when it's no longer needed.
I have a service layer that I am reusing (AKA Business Layer).
Here's an example of one of my services with an IMyContextFactory dependency, this returns an instance of IMyContext.
public class MyService : IMyService
{
private IMyContextFactory DbContextFactory;
public MyService(IMyContextFactory dbContextFactory)
{
this.DbContextFactory = dbContextFactory;
}
public DoSomething(int id)
{
// Get instance of the db for use
IMyContext dbContext = this.DbContextFactory.CreateMyDbContext();
// Use the business layer for something
var user = dbContext.Set<User>().Find(id);
}
}
I am using the Ninject Factory extension.
Is it possible to make the IMyContextFactory to return the same instance of IMyContext every time?
Background
Originally I was injecting IMyDbContext straight into the service without the factory and I had this InRequestScope() when initialized by my ASP.NET MVC website.
But now I am making use of the service it in a Windows Service too and I don't want my DbContext to become bloated because of frequent looping. I didn't want my service to be newed up for every request either, so that's why I thought a factory within the service would do the trick.
I need the best of InRequestScope() and a new instance every time depending on the configuration. I already have a separate config for ASP.NET and for the Windows Service - it's just how I get a singleton each time from the factory.
I'm not fully proficient with Ninject, but according to this page https://github.com/ninject/Ninject.Extensions.Factory/wiki/Factory-interface it seems that the instance returned by the factory is retrieved from the IResolutionRoot.
My take would be that you have to register your IMyContext concrete type with a singleton lifetime type.
(But it seems that it's not that of a good idea to not destroy your context, according to Erik Fukenbusch's comment)
I am trying to get Unity dependency injection working with a WCF service that utilises Entity Framework, but I'm getting confused about the use of context and repository.
The way I have designed it is to have a number of repository classes eg UserRepository, MessageRepository, LocationRepository, each of which accepts an EF DbContext object as a constructor parameter. This lets me control the Unit of Work at the context level, by calling context.Save() or rollback etc to control transactioning across repositories.
The confusion I'm in is that I'm not sure how to represent this in dependency injection. I want to have two scenarios
a) When the WCF service is instantiated via the WCF methods, I want it to use the DbContext class I have created and to create repository objects, passing in the created DbContext that will connect to the Entity Framework database.
b) When the WCF service methods are tested from a separate test project, I want to mock the repository objects to return mocked data.
If I was just using repository classes, this would be relatively simple as in each WCF service method I could call Container.Resolve() and then I could use the Unity WCF factory to set the concrete types for WCF instantiation, and manually configure the Unity container in my test project for the mocked types.
But the difficulty is the fact that my repositories need a DbContext class to be passed in as a constructor parameter that will survive beyond the lifetime of the repository and I also need to be able to have a reference to it in my service methods, for example
public bool CreateUser(DbUser user)
{
try
{
using (var context = new MyDbContext())
{
var repository = new UserDataRepository(context);
user.GenerateUserLight();
user.GenerateUserProfileLight();
var result = repository.InsertItem(user);
repository.Save();
return result;
}
}
catch (Exception ex)
{
return false;
}
}
How can I adapt the above method to use Unity Dependency injection so I can mock it for the test project?
As far as I can see the issue here is that you should be creating your context within your repository, the fact that you are actually newing up the context in the service and then passing it into your repository is a bit of a code smell.
Why not have the repositories handle the DbContext? That way you are not coupling your repositories to Entity Framework in the first place.
The service should only have a dependency on an IUserRepository interface.. not the concrete implementation.
private readonly IUserRepository _userRepository;
public MyService(IUserRepository userRepository)
{
this._userRepository = userRepository;
}
public bool CreateUser(DbUser user)
{
try
{
user.GenerateUserLight();
user.GenerateUserProfileLight();
var result = this._userRepository.InsertItem(user);
this._userRepository.Save();
return result;
}
catch (Exception ex)
{
return false;
}
}
The user repository would accept a DbContext in its constructor, you would need to register the context with the DI container also so that the DI can construct the UserRepository when it's injected into the service.
public class UserRepository : IUserRepository
{
private readonly MyDbContext context;
public UserRepository(MyDbContext context)
{
this.context = context;
}
}
Then you could simply inject the "UserRepository" into the service via the constructor.
This would also enable you to create Mock repository types that don't need a context at all, simply create an interface for your repository.
I have a layered application with the following projects:
DAL (using EntityFramework with repositories)
DAL.Model (contains the entities, and is referenced by all the others)
Services
UI (in wpf)
The base repository looks like this:
public abstract class RepositoryBase<T> where T : class
{
private readonly MyContext context;
private readonly IDbSet<T> dbSet;
protected RepositoryBase(MyContext dataContext)
{
context = dataContext;
dbSet = context.Set<T>();
}
protected MyContext Context
{
get { return context; }
}
**And a series of virtual methods for Add, Delete, etc.
}
All repositories extend this one, such as:
public class MarketRepository : RepositoryBase<Market>
{
public MarketRepository(MyContext dataContext) : base(dataContext)
{
}
public IEnumerable<Market> GetAllMarkets()
{
return this.Context.Markets.ToList<Market>();
}
}
The services look like this:
public class MarketService
{
IMarketRepository _marketRepository;
public MarketService(IMarketRepository marketRepository)
{
_marketRepository = marketRepository;
}
public IEnumerable<Market> GetAllMarkets()
{
return _marketRepository.GetAllMarkets();
}
}
What I would like to achieve is that the UI layer would only have a reference to the Services layer, the Services layer only with the DAL layer (and all of them to Model, where the entities live) using DI (right now I'm using Unity).
The problem is, in my container in the UI I only want to do this
unity.RegisterType<IMarketService, MarketService>();
and not have to do it as well for the repositories, because then the UI layer would have a dependency on the DAL layer.
I thought about adding a parameterless constructor to the Service classes, like:
public MarketService() : this(new MarketRepository(*What would I put here?)) { }
but then I'm loosing the abstraction that the interface gives, and also I don't know what to do with the MyContext that the repository needs as a parameter; if I pass a new one, then I need to reference the DAL.
Should I change my repositories to create a new MyContext in the constructor, rather than getting it as a parameter?
How can I refactor my architecture to make it work properly and with minimal dependencies?
Well, I belive it is up to the bootstrapper to configure dependencies, in the higher level of the application. As it is usually the UI project, if it needs to reference other assemblies, so be it. If you do not like your UI project managing that, than create a bootstrapper project responsable for getting your app running and separete your UI classes in another one.
Your IoC container should support Dependency Injection using a string from an external configuration file. This way you are not hardcoding the mapping. Structuremap does this quite well, so I am sure other IoCs will.
Adding external dependenices as a parameter when creating an instance is the way to go.
I think you should make yourself more familiar with the different ways to configure Unity, so that the dependencies are resolved.
Could you elaborate why you are creating a repository when using a dependency injection framework?
When configuring DI, you should follow the same pattern - UI bootstrapper initializes Services, Services initialize DAL. (With autofac or ninject you could achiece this using modules. With unity you should emulate modules).
In pseudocode something like
//ui
void UILayer.ConfigureUnity(unity)
{
ServiceLayer.ConfigureUnity(unity)
}
//services
void ServiceLayer.ConfigureUnity(unity)
{
DAL.ConfigureUnity(unity)
unity.RegisterType<IMarketService, MarketService>();
}
//dal
void DAL.ConfigureUnity(unity)
{
unity.RegisterType<IMarketRepository, MarketRespository>();
unity.RegisterType<MyContext, MyContext>(); //not sure exact syntax - just register type for 'new Type()' activator.
}