This is a question about how best to do DI, so it's not tied to any particular DI/IoC framework because, well, framework should be chosen based on pattern and practice rather than the other way around, no?
I'm doing a project where repository has to be injected into services, a service may require multiple repositories and I'm curious about the pros and cons between following approaches:
Inject repositories in service constructor
public class SomeService : ISomeService
{
private IRepository1 repository1;
private IRepository2 repository2;
public SomeService(IRepository1 repository1, IRepository2 repository2)
{
this.repository1 = repository1;
this.repository2 = repository2;
}
public void DoThis()
{
//Do something with repository1
}
public void DoThat()
{
//Do something with both repository1 and repository2
}
}
Inject a custom context class that include everything any service may need but lazy instantiated (the IServiceContext will be a protected field in BaseService)
public class SomeService : BaseService, ISomeService
{
public SomeService(IServiceContext serviceContext)
{
this.serviceContext= serviceContext;
}
public void DoThis()
{
//Do something with serviceContext.repository1
}
public void DoThat()
{
//Do something with both serviceContext.repository1 and serviceContext.repository2
}
}
Inject into methods that need them only
public class SomeService : ISomeService
{
public void DoThis(IRepository1 repository1)
{
//Do something with repository1
}
public void DoThat(IRepository1 repository1, IRepository2 repository2)
{
//Do something with both repository1 and repository2
}
}
Some pointers would be appreciated, moreover what're the aspects that I should consider in evaluating alternative like these?
The preferred way of injecting dependencies is Constructor Injection.
Method Injection is less ideal, because this will quickly result in having to pass around many dependencies from service to service and it will cause implementation details (the dependencies) to leak through the API (your method).
Both options 1 and 2 do Constructor Injection, which is good. If you find yourself having to inject too many dependencies in a constructor, there is something wrong. Either you are violating the Single Responsibility Principle, or you are missing some sort of aggregate service, and this is what you are doing in option 2.
In your case however, your IServiceContext aggregate service is grouping multiple repositories together. Many repositories behind one class smells like a unit of work to me. Just add a Commit method to the IServiceContext and you will surely have a unit of work. Think about it: don't you want to inject an IUnitOfWork into your service?
The first option seems to be the most natural from a DI perpective. The service class requires both repositories to perform its function, so making them required in order to construct an instance makes sense semantically (and practically).
The second option sounds a bit like Service Location, which is generally considered an anti-pattern (see http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx). In a nutshell, it creates implicit dependencies, where explicit dependencies are always preferred.
I would do either constructor based injection or property based injection. I would not pass in a context that contains the dependencies unless that context is serving some other purpose.
I prefer constructor based injection for required dependencies, as it makes it super easy for the object creation to blow up if something is missing. I got that from here. If you are going to verify that your dependencies are met, then you have to do it with constructor based injection, since there is no way to tell which setter is the last setter to be fired.
Related
I'm trying to get dependencies set up correctly in my Workflow application. It seems the best way to do this is using the Service Locator pattern that is provided by Workflow's WorkflowExtensions.
My workflow uses two repositories: IAssetRepository and ISenderRepository. Both have implementations using Entity Framework: EFAssetRepository, and EFSenderRepository, but I'd like both to use the same DbContext.
I'm having trouble getting both to use the same DbContext. I'm used to using IoC for dependency injection, so I thought I'd have to inject the DbContext into the EF repositories via their constructor, but this seems like it would be mixing the service locator and IoC pattern, and I couldn't find an easy way to achieve it, so I don't think this is the way forward.
I guess I need to chain the service locator calls? So that the constructor of my EF repositories do something like this:
public class EFAssetRepository
{
private MyEntities entities;
public EFAssetRepository()
{
this.entities = ActivityContext.GetExtension<MyEntities>();
}
}
Obviously the above won't work because the reference to ActivityContext is made up.
How can I achieve some form of dependency chain using the service locator pattern provided for WF?
Thanks,
Nick
EDIT
I've posted a workaround for my issue below, but I'm still not happy with it. I want the code activity to be able to call metadata.Require<>(), because it should be ignorant of how extensions are loaded, it should just expect that they are. As it is, my metadata.Require<> call will stop the workflow because the extension appears to not be loaded.
It seems one way to do this is by implementing IWorkflowInstanceExtension on an extension class, to turn it into a sort of composite extension. Using this method, I can solve my problem thus:
public class UnitOfWorkExtension : IWorkflowInstanceExtension, IUnitOfWork
{
private MyEntities entities = new MyEntities();
IEnumerable<object> IWorkflowInstanceExtension.GetAdditionalExtensions()
{
return new object[] { new EFAssetRepository(this.entities), new EFSenderRepository(this.entities) };
}
void IWorkflowInstanceExtension.SetInstance(WorkflowInstanceProxy instance) { }
public void SaveChanges()
{
this.entities.SaveChanges();
}
}
The biggest downside to doing it this way is that you can't call metadata.RequireExtension<IAssetRepository>() or metadata.RequireExtension<ISenderRepository>() in the CacheMetadata method of a CodeActivity, which is common practice. Instead, you must call metadata.RequireExtension<IUnitOfWork>(), but it is still fine to do context.GetExtension<IAssetRepository>() in the Execute() method of the CodeActivity. I imagine this is because the CacheMetadata method is called before any workflow instances are created, and if no workflow instances are created, the extension factory won't have been called, and therefore the additional extensions won't have been loaded into the WorkflowInstanceExtensionManager, so essentially, it won't know about the additional extensions until a workflow instance is created.
I'm trying to implement passive attributes in an ASP.NET Web API. The filter I'm implementing has a dependency on a repository, which itself has a dependency on a custom DbContext.
In the post it says that you can resolve the component with a DI container, but also that the code should be invoked from Application_Start.
I'm not sure how to implement this, while taking advantage of the DI container's lifetime management capabilities (so that a new DbContext will be used per request). Would injecting an abstract factory be a good solution for this? or is there something simpler that I'm missing.
You can resolve this issue by sliding a Decoraptor in between the Filter and the Repository.
Not knowing a lot about your code, you should be able to define a Decoraptorepository using an Abstract Factory:
public class Decoraptorepository : IRepository
{
private readonly IFactory<IRepository> factory;
public Decoraptorepository(IFactory<IRepository> factory)
{
this.factory = factory;
}
// Just guessing IRepository's member(s) here...
public void Save(Foo foo)
{
this.factory.Create().Save(foo);
}
// other members...
}
This enables your Filter to stay a Singleton, while the actual Repository is being created in a Transient manner.
If you need to dispose of objects too, please refer to the follow-up article on how to decommission Transient objects from within a Decoraptor.
What pattern would one use if you have multiple factory implementations, each of which requires different state information to create new objects?
Example:
IModelParameters: contains all the inputs and outputs to a complex calculation
IModelParameterFactory: has methods for getting and saving IModelParameter objects.
The issue is that one factory implementation might be getting your parameters from a database, with some state needed for retrieval, (i.e. a UserID), another might be getting your inputs from a file, in which case you don't have a UserID, but you do need a file name.
Is there another pattern that works better in this case? I've looked at some dependancy injection tools/libraries, and haven't seen anything that seems to address the situation.
Have you tried to put the requeriments in a class?
Every factory implementation has their own requeriments, but all requeriments classes derives form a base requeriment class (Or impements a requeriments interface). This allows you to have the same interface for all factory implementations, you just must do a cast to the correct requeriments class in every factory implementation.
Yes, casts are ugly and error-prone, but this method provides an uniform an extensible interface for your factory.
It's hard to say without seeing some code, but you may want to look into implementing a Repository Pattern. The Repository implementation would be responsible for retrieving the data that the factory then used to build its object(s). You could inject the repository interface into your factory:
public class ModelParameterFactory : IModelParameterFactory
{
private readonly IModelParameterRepository Repository;
public ModelParameterFactory(IModelParameterRepository repository)
{
Repository = repository;
}
...interface methods use the injected repository...
}
Then you would have, say a DatabaseModelParameterRepository and a FileModelParameterRepository. But I'm guessing you also have logic around which of those you would need to inject, so that calls for another factory:
public class ModelParameterRepositoryFactory : IModelParameterRepositoryFactory
{
public ModelParameterRepositoryFactory(...inputs needed to determine which repository to use...)
{
...assign...
}
...determine which repository is required and return it...
}
At this point, it might make more sense to inject IModelParameterRepositoryFactory into the ModelParameterFactory, rather than inject the IModelParameterRepository.
public class ModelParameterFactory : IModelParameterFactory
{
private readonly IModelParameterRepositoryFactory RepositoryFactory;
public ModelParameterFactory(IModelParameterRepositoryFactory repositoryFactory)
{
RepositoryFactory = repositoryFactory;
}
...interface methods get repository from the factory...
}
Whether you use a DI container or not, all logic regarding which repository to use and which factory to use are now moved into the relevant factory implementations, as opposed to the calling code or DI configuration.
While not terribly complex, this design nonetheless does give me pause to wonder whether your ModelParameterFactory and ModelParameters are too generic. You might benefit from teasing them into separate, more specific classes. The result would be a simpler and more expressive design. The above should work for you if that is not the case, however.
In my point of view, a state is something that you store in memory, such as static object, global variable, cache or session. Usually in DI, such states are not maintained, but being passed as a parameter. Example:
public IEnumerable<Records> GetRecordByUserId(string userId){ /*code*/ }
The userId is being passed instead being maintained in the repository.
However, when you want to make them as configuration-like instead of passing each time you do query, I think you can inject it as a wrapper class. See my question for more info. However, I don't recommend this design at repository, but I do recommend at service level.
I've run into a bit of a problem with EF looking for the best practice for this problem:
public void TestEntityFramework_UOWImplementation()
{
using (UnitOfWorkInventory uow = new UnitOfWorkInventory())
{
IMaterialRepository repos = new MaterialRepository(uow);
Material mat = GetMaterial("Mikes Material", 1);
mat.CostPrice = 20;
repos.InsertOrUpdate(mat);
uow.Commit();
}
}
private Material GetMaterial(string sku, int clientId)
{
IMaterialRepository repos = new MaterialRepository(new UnitOfWorkInventory();
return repos.Find(sku, clientId);
}
In the TestEntityFramework_UOWImplementation() method, its fine, i call create a scope for my unit of work.. and create a repository inside it.
But when i want to getMaterials() as below.. I have no access to the unit of work or the repository, unless i actually pass it as a parameter! This is clearly not particularly nice.
How do people get around this problem??
Thanks in advance!
Neil
In your implementation you wont have access to the Unit of Work like that. What I do is use an IoC container and Dependency Injection to handle it. I have a WCF service that uses Unit of Work with a repository pattern against EF5.
You can read more about repository pattern, unit of work, and EF here but basically what I do is in the constructor of my service class I inject the Unit of Work like so:
private readonly IUnitOfWork uow;
public LoanService(IUnitOfWork unitOfWork)
{
uow = unitOfWork;
}
Then I can use uow.WhateverMethod in my repos anywhere in the service. I use Ninject to handle the injection of IUnitOfWork. Hope it helps you.
If anyone was looking for a way around this, I done something a bit different.
I used a Dependency Injection framework (StructureMap) to handle all DI, so everytime i instantiate a repository it will retrieve the DBContext from the Service Locator of StructureMap. I also make the dbcontext scope to be for the duration of the request from the webserver.
The advantage here being that everytime i retrieve or inject a DBContext, it will retrieve the same context for the duration of the request meaning i can use this across multiple methods and class! I pass the interface type as a generic param to the constructor, meaning that i can point the repo as different contexts. Helpful in applications where there are lots of dbcontexts.
Repo Constructor Eg:
public class PurchaseOrderRepository<TDbContext> : GenericRepository<PurchaseOrder>, IPurchaseOrderRepository<TDbContext> where TDbContext : DbContext
{
public PurchaseOrderRepository()
: base((TDbContext)ObjectFactory.GetInstance<TDbContext>())
{
}
}
Usage:
//resolves the request scope InventoryContext...
var pRepos = new PurchaseOrderRepository<IInventoryContext>();
and the structure map dependency looks like:
For<IInventoryContext>().HttpContextScoped().Use<InventoryContext>();
I have a WPF application based on MVVM with Caliburn.Micro and Ninject. I have a root viewmodel called ShellViewModel. It has a couple of dependencies (injected via constructor) which are configured in Caliburn's Bootstrapper. So far so good.
Somewhere down the line, there is a MenuViewModel with a couple of buttons, that in turn open other viewmodels with their own dependencies. These viewmodels are not created during creation of the root object, but I still want to inject dependencies into them from my IoC container.
I've read this question on service locator vs dependency injection and I understand the points being made.
I'm under the impression however that my MenuViewModel needs to be able to access my IoC container in order the properly inject the viewmodels that are being made dynamically..which is something I'm trying to avoid. Is there another way?
Yes, I believe you can do something a bit better.
Consider that if there was no on-demand requirement then obviously you could make those viewmodels be dependencies of MenuViewModel and so on up the chain until you get to the root of the object graph (the ShellViewModel) and the container would wire everything up.
You can put a "firewall" in the object graph by substituting something that can construct the dependencies of MenuViewModel for the dependencies themselves. The container is the obvious choice for this job, and IMHO from a practical standpoint this is a good enough solution even if it's not as pure.
But you can also substitute a special-purpose factory instead of the container; this factory would take a dependency on the container and provide read-only properties for the real dependencies of MenuViewModel. Accessing the properties would result in having the container resolve the objects and returning them (accessor methods would also work instead of properties; what's more appropriate is another discussion entirely, so just use whatever you think is better).
It may look like that you haven't really changed the status quo, but the situation is not the same it would be if MenuViewModel took a direct dependency on the container. In that case you would have no idea what the real dependencies of MenuViewModel are by looking at its public interface, while now you would see that there's a dependency on something like
interface IMenuViewModelDependencyFactory
{
public RealDependencyA { get; }
public RealDependencyB { get; }
}
which is much more informative. And if you look at the public interface of the concrete MenuViewModelDependencyFactory things are also much better:
class MenuViewModelDependencyFactory : IMenuViewModelDependencyFactory
{
private Container container;
public MenuViewModelDependencyFactory(Container container) { ... }
public RealDependencyA { get { ... } }
public RealDependencyB { get { ... } }
}
There should be no confusion over what MenuViewModelDependencyFactory intends to do with the container here because it's so very highly specialized.