In the code I am working on I have a structure where some portions of the code depend on the current software session. Software session contains multiple helper objects which are dependency injected by composition.
One example is IRepository injected to it, which contains access to the data repository. And the IRepository contains a DatabaseContext which writes to a database, via IDbContext again which is injected.
SoftwareSession is the only injected common infrastructure for accessing all the way to the database, acting as a gateway. This means when I want to write an object to database, for instance WriteCar I will have to implement 3 interfaces, 2 functions delegating to composed objects and 1 function with implementation. It is clarified in the code fragment below. The WriteCar signatures are defined the same in 3 interfaces (IRepository, ISoftwareSession, IDbContext), 2 places where it is not implemented (Repository, SoftwareSession) which simply calls composited objects related functions and 1 place of actual implementation (IDbContext)
This means when I want to refactor, move code, add functionality or change function signatures I will always have to change 6 places for one function.
I think this provides the best environment for improving testability and it follows best practices where software session wraps access to repository and repository wraps access to data contexts - yet I still am questioning if we can have some better way of writing it once, or do I have a misunderstanding of some concept in the code below?
What is the architecturally more maintainable way of implementing this? Maybe even using some clever way of lambdas or delegates to reduce the amount of code written for each new functionality? Or even some libraries (like automapper simplifies DTOs) or tools to ease generation of this code from some kind of templating mechanism using Visual Studio, Resharper, etc?
Please let me know if I am having some confusion of concepts here. I know some my colleagues have similar views, in which case it may be helpful to clarify misunderstandings of others as well.
public class SoftwareSession : ISoftwareSession
{
...
IRepository repository;
public void WriteCar(Car car){
repository.WriteCar(car);
}
...
}
public interface ISoftwareSession{
...
void WriteCar(Car car);
...
}
public class Repository : IRepository{
...
IDbContext context;
public void WriteCar(Car car){
context.WriteCar(car);
}
...
}
public interface IRepository{
...
void WriteCar(Car car);
...
}
public class MyDbContext : IDbContext{
...
public void WriteCar(Car car){
//The Actual Implementation here.
...
}
...
}
public interface IDbContext{
...
void WriteCar(Car car);
...
}
For one thing, your IDbContext and IRepository are the same. You would probably like to remove IDbContext, or at least to remove methods declared in IRepository from it.
Then, both MyDbContext and Repository would implement IRepository and Repository class would just be a wrapper around MyDbContext.
Then, if Repository is only forwarding calls to MyDbContext, then you probably don't need that class either.
Furthermore, I don't see that you are doing anything in the SoftwareSession apart from forwarding the call to the contained repository. Do you really need SoftwareSession, or would it make sense to pass IRepository directly to whoever is calling the session object?
Bottom line is that this implementation is swarming with duplication and forwarding. Remove that, and your entire model would become simple.
Without seeing your composition root, I'm not entirely sure how your implementation works, but I'd suggest looking into using an Inversion of Control (IoC) container. Since your ISoftwareSession implementation only depends on an IRepository instance, you only need to inject that in the class' constructor. The same goes for your IRepository implementation: you only need to inject your IDbContext into the constructor.
With the IoC container, you "register", i.e. wire up your interfaces to your implementation at application startup (in the composition root), and the container takes care of creating the required instances when you resolve the dependencies. Then all you have to do is get the instance of SoftwareSession from the container, and away you go.
So, you could change your SoftwareSession implementation like this:
public class SoftwareSession : ISoftwareSession
{
IRepository repository;
public SoftwareSession(IRepository repository)
{
this.repository = repository;
}
public void WriteCar(Car car)
{
repository.WriteCar(car);
}
}
And your Repository implementation like this:
public class Repository : IRepository
{
IDbContext context;
public Repository(IDbContext dbContext)
{
context = dbContext;
}
public void WriteCar(Car car)
{
context.WriteCar(car);
}
}
Then here is your composition root:
var ioc = new MyIocContainer();
// register your interfaces and their associated implementation types with the IoC container
ioc.Register<ISoftwareSession, SoftwareSession>();
ioc.Register<IRepository, Repository>();
ioc.Register<IDbContext, MyDbContext>();
// resolve the IoC container
ioc.Resolve();
// get your `ISoftwareSession` instance
var session = ioc.GetConcrete<ISoftwareSession>();
var newCar = new Car();
session.WriteCar(newCar);
Related
Introduction
Hi everyone, I'm currently working on a persistence library in C#. In that library, I have implemented the repository pattern where I'm facing a SOLID issue.
Here is a simplified example my current implementation to focus on the essential:
The abstract repository containing in the persistence library:
public abstract class Repository<T>
{
protected Repository(
IServiceA serviceA,
IServiceB serviceB)
{
/* ... */
}
}
The concrete repository created by the library user:
public class FooRepository : Repository<Foo>
{
protected FooRepository(
IServiceA serviceA,
IServiceB serviceB) :
base(serviceA, serviceB)
{
/* ... */
}
}
Problem
OK, with the current code, the derived class has to know every dependency of the base class which can be ok, but what if I add a dependency to the base class? Every derived class will break because they will need to pass that new dependency to the base class... So currently, I'm limited to never change the base class constructor and it's a problem because I want my base class to had the possibility to evolve. This implementation clearly breaks the Open/Closed Principle, but I don't know how to solve this issue without breaking the SOLID...
Requirements
The library should be easy to use for the user
The concrete repositories should be able to be constructed through the DI
One or more dependencies should be added to the abstract repository without impacting the derived repositories
It should be possible to register every repository in the DI container using a naming convention as does the ASP.NET MVC framework with the controllers
The user should be able to add more dependencies in his derived repository if he wants
Solutions already envisaged
1. Service aggregator pattern
Following this article, the service aggregator model can be applied in this situation so the code would look like something like this:
The abstract repository containing in the persistence library:
public abstract class Repository<T>
{
public interface IRepositoryDependencies
{
IServiceA { get; }
IServiceB { get; }
}
protected Repository(IRepositoryDependencies dependencies)
{
/* ... */
}
}
The concrete repository created by the library user:
public class FooRepository : Repository<Foo>
{
protected Repository(IRepositoryDependencies dependencies) :
base(dependencies)
{
/* ... */
}
}
Pros
The derived classes don't break if a dependency is added to the base class
Cons
The implementation of the IRepositoryDependencies interface has to be modified if we add a dependency
The article doesn't explain how to use Castle DynamicProxy2 (which is an unknown technology for me) to dynamically generate the service aggregator
2. Builder pattern
Perhaps, it's possible to remove the base repository constructor and introduce a builder template to create the repositories, but for this solution to work, the builder must be inheritable to allow the user to enter his repository own dependencies.
Pros
The derived classes don't break if a dependency is added to the base class
The repositories construction is managed by another class
Cons
The user has to create a builder for each repository he wants to create
It's become harder to register every repository through the DI using a naming convention
3. Property injection
Perhaps removing the base repository constructor and configuring the DI to use property injection might be an option.
Pros
The derived classes don't break if a dependency is added to the base class
Cons
I think the property setter must be public?
Conclusion
Is there any of the mentioned solutions that could be acceptable in a SOLID world? If not, do you have a solution for me guys? You help is very appreciated!
After some years of experience, I found the Decorator Pattern a perfect fit for this.
Implementation:
// Abstract type
public interface IRepository<T>
{
Add(T obj);
}
// Concete type
public class UserRepository : IRepository<User>
{
public UserRepository(/* Specific dependencies */) {}
Add(User obj) { /* [...] */ }
}
// Decorator
public class LoggingRepository<T> : IRepository<T>
{
private readonly IRepository<T> _inner;
public LoggingRepository<T>(IRepository<T> inner) => _inner = inner;
Add(T obj)
{
Console.Log($"Adding {obj}...");
_inner.Add(obj);
Console.Log($"{obj} addded.");
}
}
Usage:
// Done using the DI.
IRepository<User> repository =
// Add as many decorators as you want.
new LoggingRepository<User>(
new UserRepository(/* [...] */));
// And here is your add method wrapped with some logging :)
repository.Add(new User());
This pattern is awesome, because you can encapsulate behaviors in separate classes without breaking changes and using them only when you really need them.
As asked by you, here is one very basic and crude sample of solving this problem through Composition rather than inheritance.
public class RepositoryService : IRepositoryService
{
public RepositoryService (IServiceA serviceA, IServiceB serviceB)
{
/* ... */
}
public void SomeMethod()
{
}
}
public abstract class Repository
{
protected IRepositoryService repositoryService;
public (IRepositoryService repositoryService)
{
this.repositoryService= repositoryService;
}
public virtual void SomeMethod()
{
this.repositoryService.SomeMethod()
.
.
}
}
public class ChildRepository1 : Repository
{
public (IRepositoryService repositoryService) : base (repositoryService)
{
}
public override void SomeMethod()
{
.
.
}
}
public class ChildRepository2 : Repository
{
public (IRepositoryService repositoryService, ISomeOtherService someotherService) : base (repositoryService)
{
.
.
}
public override void SomeMethod()
{
.
.
}
}
Now, the abstract base class and each child repository class here will only depend on IRepositoryService or any other required dependency (refer ISomeOtherService in ChildRepository2).
This way your child repository only supplies IRepositoryService dependency to your base class and you do not need to supply the dependencies of IRepositoryService anywhere.
It might be a bit late, but you can use the IServiceProvider in the constructor instead:
The abstract repository containing in the persistence library:
public abstract class Repository<T>
{
protected Repository(IServiceProvider serviceProvider)
{
serviceA = serviceProvider.GetRequiredService<IServiceA>();
serviceB = serviceProvider.GetRequiredService<IServiceB>();
/* ... */
}
}
The concrete repository created by the library user:
public class FooRepository : Repository<Foo>
{
protected FooRepository(IServiceProvider serviceProvider)
:base(serviceProvider)
{
serviceC = serviceProvider.GetRequiredService<IServiceC>();
serviceD = serviceProvider.GetRequiredService<IServiceD>();
/* ... */
}
}
This way each of the classes can utilize their own services without any cross-dependency.
There are downsides to this approach. First, this is a sort of service locator (anti)pattern with an abstract locator, though that does not mean it's not supposed to be used anywhere. Just be judicial about it, and make sure there isn't a better solution.
Second, there is no compile-time enforcement to supply the necessary service implementations to any of the repository classes. Meaning, this will still compile if you do not put concrete implementation of IServiceA into the service provider. And then, it will fail run-time. However, in this case, that was one of your requirements.
The conclusion "I'm limited to never change the base class constructor " is pure demonstration how heavy IoC container "pattern" is toxic.
Imagine you have an asp application and want to have the possibility to enable logging for specific user the way when each his session goes to new file. It is impossible to achieve with IoC Containers / Service locators / ASP Controllers constructor. What you can do: on each session start you should create such logger and accurately pass it through all constructors (service realizations etc deeper and deeper). There are no other ways. There are no such things as "per session" life cycle in IoC containers - but this is only one way which instances naturally should live in ASP (means multiuser/multitask app).
If you do not have DI through constructor you are definitely doing something wrong (this is true for ASP.CORE and EF.CORE - it is impossible to watch how they torture everybody and themself with abstraction leaks: can you imagine that adding custom logger broke the DbContext https://github.com/aspnet/EntityFrameworkCore/issues/10420 and this is normal?
Get from DI only configuration or dynamic plugins (but if you do not have dynamic plugins do not think of any dependency "as it could be a dynamic plugin") and then do all DI standard classic way - through constructor.
I've been gifted having had to work with an already set up Ninject DI based application which I have grown and added to considerably over the development of an application I'm working on.
I now find a problem that I would like to correct. I've managed to work around it using inheritance but would like a more cleaner solution.
I have two connections required to be injected into different services and repositories. I then need the repositories to also be correctly linked to the correct service having the same UnitOfWork.
I think I might be asking something that is not possible without inheritance and specialisation but that is why I am asking.
I managed to resolve this by creating a sub class of the main Repository and UnitOfWork classes but does nothing apart from implementing the base class.
I just don't like the idea of a sub class that is fully dependant on the super class functionality with basically empty braces apart from constructor, to me this doesn't seem true OOP just to resolve this problem. So I sought for a better solution utilising a one class solution if possible in DI.
So if you can ignore the solution I have spoken about because I completely reverted the change this is what I am left with:
Looking at the code below you can see what is the objective.
...
public class UnitOfWork : IUnitOfWork
{
private static readonly log4net.ILog log = log4net.LogManager.GetLogger("UnitOfWork");
public DbContext DataContext { get; set; }
public UnitOfWork(string connectionString)
{
DataContext = new DbContext(connectionString);
}
public void Commit()
{
...
}
}
...
public class Repository<T> : IRepository<T> where T : class
{
public IUnitOfWork unitOfWork { get; set; }
private readonly IDbSet<T> dbSet;
//private static readonly log4net.ILog log = log4net.LogManager.GetLogger("Repository");
public Repository(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
dbSet = this.unitOfWork.DataContext.Set<T>();
}
...
}
...
public class IPOPDataModules : NinjectModule
{
public override void Load()
{
Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope().WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["IPOP_BE_TESTEntities"].ConnectionString);
Bind<IRepository<tOrder>>().To<Repository<tOrder>>().InRequestScope();
}
}
...
public class DataModules : NinjectModule
{
public override void Load()
{
Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope().WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["IPOP_BAPSEntities"].ConnectionString);
Bind<IRepository<Data.Quote>>().To<Repository<Data.Quote>>().InRequestScope();
}
}
...
public class QuoteService : IQuoteService
{
private IUnitOfWork unitOfWork;
private IRepository<Data.Quote> quoteRepository;
public QuoteService(IUnitOfWork unitOfWork, IRepository<Data.Quote> quoteRepository)
{
...
}
}
...
public class IPOPService : IIPOPService
{
private IUnitOfWork unitOfWork;
private IRepository<Data.tOrder> tOrderRepository;
public IPOPService(IUnitOfWork unitOfWork, IRepository<Data.tOrder>)
{
...
}
}
What I want to know is, is it possible to share the same UnitOfWork and Repository objects by two different connections and have them injected as different instances to the respective services (IPOPService for IPOP_BE_TEST connection, QuoteService for IPOP_BAP connection)
Again the code above doesn't achieve want I want but this is the sort of architecture I would like to play around to get this to work.
What you're looking for are Ninject binding scopes. Whenever you declare a binding Ninject will provide a delegate to that binding that the activation process uses to determine if it should create a new instance of that service, or if it should return a previously constructed instance.
So, if you want to implement a singleton in Ninject, you simply declare a binding that looks like this:
Bind<IRepository<Data.Quote>>().To<Repository<Data.Quote>>().InSingletonScope();
InSingletonScope() and InRequestScope() are simply sugar (or in the case of InRequestScope an extension method) on IBindingInSyntax<T> for the InScope(Func<Ninject.Activation.IContext, object> scope) method though. Any time you want to ensure that Ninject returns the same instance of a service in a given situation, all you need to do is implement a custom scope.
If I understand your question correctly, you want to ensure that when a request hits your application the same instances of Repository<T> and IUnitOfWork will be injected into all the services in your application. In this case you would simply have to write bindings like this:
Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope().WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["IPOP_BE_TESTEntities"].ConnectionString);
Bind<IRepository<tOrder>>().To<Repository<tOrder>>().InRequestScope();
However, your problem appears to be that you have two separate modules, with two separate bindings. I would suggest that you need to use a single module with contextual binding to determine which connection string should be provided to which part of the system. So your one module might look like this:
Bind<IUnitOfWork>()
.To<UnitOfWork>()
.WhenInjectedInto<IIPOPService>()
.InRequestScope()
.WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["IPOP_BE_TESTEntities"].ConnectionString);
Bind<IUnitOfWork>()
.To<UnitOfWork>()
.WhenInjectedInto<IQuoteService>()
.InRequestScope()
.WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["IPOP_BAPSEntities"].ConnectionString);
Bind<IRepository<tOrder>>().To<Repository<tOrder>>().InRequestScope();
This way you can be sure that when Ninject is resolving IIPOPService it will create an instance of UnitOfWork initialized with the "IPOP_BE_TESTEntities" connection string, and when resolving IQuoteService, it will use the "IPOP_BAPSEntities" connection string, but otherwise, across that request scope, only a single instance will be constructed by Ninject.
Hope this helps.
Your question is not completely clear for me. But check the documentation for the following two scopes, which might be interesting for your scenario.
InCallScope will result that only one instance will be created per resolution tree. I usually use this scope on desktop applications for a unit of work. See the documentation here. You'll need the Ninject.Extensions.NamedScope extension for this.
InRequestScope will result that in a web application, only one instance will be created per HTTP request. I usually use this scope for a unit of work. See the documentation here. You'll need the Ninject.Web.Common package for this.
Building a app with EF 6 and Ninject 3.2.2 I'm having some trouble wrapping my head around how to access the DbContext in a intelligent way.
As I understand in the newer versions of Ninject only constructor injection is encouraged. As EF 6, itself is repo and unit of work I'm not doing any abstractions on top of EF.
If would like to be able to use multiple small units of works so injecting the DbContext (uow) into every class that needs it is not going to work.
In a non IoC way I would do like this:
Using(var db = new DbContext){}
How do achieve this using Ninject as I no longer can do kernel.get in my using block...
I'd consider two approaches:
Create general DbContext, which can be hidden behind an interface:
public interface IPortalContext : IDisposable
{
DbSet<User> Users { get; }
DbContext Context { get; }
}
public class PortalContext : DbContext, IPortalContext
{
public PortalContext()
: base("PortalConnectionString")
{
}
public virtual DbSet<User> Users { get; set; }
}
then you can inject your context to the constructor without problem.
Create many small contexts which can be used in different scenarios and classes.
I don't think that first approach is bad since it only encapsulates your DbSets and DbContext making it easier to inject and test. You don't make any unnecessary layers above EF and whole interface seems quite transparent.
Anyway this approach is better than making whole IRepository<T> stuff to access another repository...
I'm not sure what you mean by "multiple small unit of works", but just for exposure, this is what I've done in a recent application:
Divided the domain in small bounded contexts (this is more of a conceptual step)
Each bounded context has: a context, a repository, a repository factory
Each context implements an IContext and a BaseContext that gives basic methods and common properties (IContext will be useful for mocking)
Each repository takes the relative context as a constructor paramenter
This is an example of a repository factory
public class CartRepositoryFactory : IRepositoryFactory
{
public IRepository Generate(CartContext ctx)
{
return new CartRepository(ctx);
}
}
At the application service layer, I inject a UoW and the repository factory that I need
If I want to work with several different context in one service, I simply create another service and combine the services that I need, injecting them
You might be asking, but why?!? This is madness!!
Well, because if the Repository manages the DbContext, then I can only do one operation per class instantiation. This allows me to open a DbContext and make several calls to the Repository.
Of course now you have the same problem at application service level, you can only call one method per instantiation, but it's far easier to manage.
Ultimately it all comes down to your taste: would you rather have a thin service or a thin repository?
I've been reading up on how to write testable code and stumbled upon the Dependency Injection design pattern.
This design pattern is really easy to understand and there is really nothing to it, the object asks for the values rather then creating them itself.
However, now that I'm thinking about how this could be used the application im currenty working on I realize that there are some complications to it. Imagine the following example:
public class A{
public string getValue(){
return "abc";
}
}
public class B{
private A a;
public B(A a){
this.a=a;
}
public void someMethod(){
String str = a.getValue();
}
}
Unit testing someMethod () would now be easy since i can create a mock of A and have getValue() return whatever I want.
The class B's dependency on A is injected through the constructor, but this means that A has to be instantiated outside the class B so this dependency have moved to another class instead. This would be repeated many layers down and on some point instantiation has to be done.
Now to the question, is it true that when using Dependency Injection, you keep passing the dependencys through all these layers? Wouldn't that make the code less readable and more time consuming to debug? And when you reach the "top" layer, how would you unit test that class?
I hope I understand your question correctly.
Injecting Dependencies
No we don't pass the dependencies through all the layers. We only pass them to layers that directly talk to them. For example:
public class PaymentHandler {
private customerRepository;
public PaymentHandler(CustomerRepository customerRepository) {
this.customerRepository = customerRepository;
}
public void handlePayment(CustomerId customerId, Money amount) {
Customer customer = customerRepository.findById(customerId);
customer.charge(amount);
}
}
public interface CustomerRepository {
public Customer findById(CustomerId customerId);
}
public class DefaultCustomerRepository implements CustomerRepository {
private Database database;
public CustomerRepository(Database database) {
this.database = database;
}
public Customer findById(CustomerId customerId) {
Result result = database.executeQuery(...);
// do some logic here
return customer;
}
}
public interface Database {
public Result executeQuery(Query query);
}
PaymentHandler does not know about the Database, it only talks to CustomerRepository. The injection of Database stops at the repository layer.
Readability of the code
When doing manual injection without framework or libraries to help, we might end up with Factory classes that contain many boilerplate code like return new D(new C(new B(), new A()); which at some point can be less readable. To solve this problem we tend to use DI frameworks like Guice to avoid writing so many factories.
However, for classes that actually do work / business logic, they should be more readable and understandable as they only talk to their direct collaborators and do the work they need to do.
Unit Testing
I assume that by "Top" layer you mean the PaymentHandler class. In this example, we can create a stub CustomerRepository class and have it return a Customer object that we can check against, then pass the stub to the PaymentHandler to check whether the correct amount is charged.
The general idea is to pass in fake collaborators to control their output so that we can safely assert the behavior of the class under test (in this example the PaymentHandler class).
Why interfaces
As mentioned in the comments above, it is more preferable to depend on interfaces instead of concrete classes, they provide better testability(easy to mock/stub) and easier debugging.
Hope this helps.
Well yes, that would mean you have to pass the dependencies over all the layers. However, that's where Inversion of Control containers come in handy. They allow you to register all components (classes) in the system. Then you can ask the IoC container for an instance of class B (in your example), which would automatically call the correct constructor for you automatically creating any objects the constructor depends upon (in your case class A).
A nice discussion can be found here: Why do I need an IoC container as opposed to straightforward DI code?
IMO, your question demonstrates that you understand the pattern.
Used correctly, you would have a Composition Root where all dependencies are resolved and injected. Use of an IoC container here would resolve dependencies and pass them down through the layers for you.
This is in direct opposition to the Service Location pattern, which is considered by many as an anti-pattern.
Use of a Composition Root shouldn't make your code less readable/understandable as well-designed classes with clear and relevant dependencies should be reasonably self-documenting. I'm not sure about unit testing a Composition Root. It has a discreet role so it should be testable.
I'm out of ideas how to configure right Windsor container for use with repositories in Windows app.
I have generic repository implementation Repository, where T is entity type, it has a dependency IDatacontextProvider, which provides datacontext for it:
public class Repository<T> : IRepository<T> where T : class
{
protected DataContext DataContext;
public Repository(IDataContextProvider dataContextProvider) {
DataContext = dataContextProvider.DataContext;
}
....
}
And for simple things everything works ok with following configuration:
container.Register(
Component.For<IDataContextProvider>()
.ImplementedBy<DataContextProvider>()
.Lifestyle.Transient,
Component.For(typeof(IRepository<>))
.ImplementedBy(typeof(Repository<>))
.Lifestyle.Transient, ....
Problems occur, when i try to join different entities from several repositories, as long as each repository instance has different data context instance.
For example i have simple service:
public class SimpleService : ISimpleService {
public SimpleService(IRepository<Order>, IRepository<OrderLine>) {
....
}
}
I could make IDataContextProvider as Singleton, but i think that would bring even bigger problems.
I could pass IDataContextProvider to SimpleService, and try to resolve repository instances there, but that would require additional code to make service easy testable and would require additional dependencies.
May be somebody has a better idea how to solve this?
update:
following advice, I've created repository factory (it's little bit different from proposed in answer, it does not have direct dependency to datacontext, but idea is very same):
public interface IRepositoryFactory
{
IRepository<T> GetRepository<T>() where T:class;
}
public class RepositoryFactory : IRepositoryFactory
{
private readonly IDataContextProvider dataContextProvider;
public RepositoryFactory(IDataContextProvider dataContextProvider)
{
this.dataContextProvider = dataContextProvider;
}
public IRepository<T> GetRepository<T>() where T : class
{
return new Repository<T>(dataContextProvider);
}
}
What about having another layer in between, such as a RepositoryFactory? That one could have a transient lifestyle. All repositories created from the factory would share the same DataContext instance. You would also need to change your repository classes so they take a DataContext instance instead of a DataContextProvider.
public class RepositoryFactory : IRepositoryFactory
{
protected DataContext dataContext;
public RepositoryFactory(IDataContextProvider provider)
{
dataContext = dataContextProvider.DataContext;
}
public IRepository<T> GetRepository<T>()
{
return new Repository<T>(dataContext);
}
}
public class SimpleService : ISimpleService {
public SimpleService(IRepositoryFactory factory) {
....
}
}
IDatacontextProvider sounds like a factory interface and these are usually defined as singletons in the dependency injection. I see several potential paths to a solution:
I don't know about particulars of your application, but maybe you can write your own lifestyle manager for IDatacontextProvider (since you say neither singleton nor transient suits you).
If you want to ensure the same IDatacontextProvider is passed among repositories, maybe you should think about providing it explicitly as a method parameter, instead of an injected dependency.
#Can's answer is also a possible solution, I've used that one myself once.
Your problem is in the configuration of the lifestyle. I had the same issues. You have to configure your repositories with an PerWebRequest lifestyle. This gave me an nice performance boost and reducing my errors from dozens to zero.
On my blog you can find an simple example http://marcofranssen.nl of dependency injection in combination with mvc3 and EF Code first.