In the following code, the HomeController receives a ValueObject whose state someValue changes so often in the DB. The state is retrieved in the constructor.
How can I register the HomeController in the container using IHomeController so whenever the HomeController is accessed, a new ValueObject is created as well as it's state is updated as well?
public class HomeController()
{
public HomeController(ValueObject value)
{
}
}
public class ValueObject()
{
public someValues { get; private set; }
public ValueObject(IValueRepository repository)
{
// The someValue changes very often in the system
someValue = repository.GetSomeValues();
}
}
This should work:
container.Register<HomeController>();
container.Register<ValueObject>();
container.Register<IValueRepository, SqlValueRepository>();
From a DI perspective, your ValueObject is troublesome, because it calls its dependencies in its constructor. Injection constructors however, should be simple and reliable.
So if your intention is to cache the SomeValues, a better design is to use a decorator. For instance
public class CachingValueRepositoryDecorator : IValueRepository
{
private readonly Lazy<SomeValues> values;
public CachingValueRepositoryDecorator(IValueRepository decoratee)
{
this.values = new Lazy<SomeValues>(decoratee.GetSomeValues);
}
public SomeValues GetSomeValues() => this.values.Value;
}
Such decorator allows you to remove the need to have a ValueObject in the HomeController which can simply look as follows:
public class HomeController
{
public HomeController(IValueRepository repository)
{
}
}
This can be registered as follows:
container.Register<HomeController>();
container.Register<IValueRepository, SqlValueRepository>();
container.RegisterDecorator<IValueRepository, CachingValueRepositoryDecorator>();
I am familiar with these patterns but still don't know how to handle following situation:
public class CarFactory
{
public CarFactory(Dep1,Dep2,Dep3,Dep4,Dep5,Dep6)
{
}
public ICar CreateCar(type)
{
switch(type)
{
case A:
return new Car1(Dep1,Dep2,Dep3);
break;
case B:
return new Car2(Dep4,Dep5,Dep6);
break;
}
}
}
In general the problem is with amount of references that needs to be injected. It will be even worse when there are more cars.
First approach that comes to my mind is to inject Car1 and Car2 in factory constructor but it is against factory approach because factory will return always the same object. The second approach is to inject servicelocator but it's antipattern everywhere. How to solve it?
Edit:
Alternative way 1:
public class CarFactory
{
public CarFactory(IContainer container)
{
_container = container;
}
public ICar CreateCar(type)
{
switch(type)
{
case A:
return _container.Resolve<ICar1>();
break;
case B:
return _container.Resolve<ICar2>();
break;
}
}
}
Alternative way 2 (too hard to use because of too many of dependencies in tree):
public class CarFactory
{
public CarFactory()
{
}
public ICar CreateCar(type)
{
switch(type)
{
case A:
return new Car1(new Dep1(),new Dep2(new Dep683(),new Dep684()),....)
break;
case B:
return new Car2(new Dep4(),new Dep5(new Dep777(),new Dep684()),....)
break;
}
}
}
Having a switch case statement inside of a factory is a code smell. Interestingly, you don't seem to be focusing on solving that issue at all.
The best, most DI friendly solution for this scenario is the strategy pattern. It allows your DI container to inject the dependencies into the factory instances where they belong, without cluttering up other classes with those dependencies or resorting to a service locator.
Interfaces
public interface ICarFactory
{
ICar CreateCar();
bool AppliesTo(Type type);
}
public interface ICarStrategy
{
ICar CreateCar(Type type);
}
Factories
public class Car1Factory : ICarFactory
{
private readonly IDep1 dep1;
private readonly IDep2 dep2;
private readonly IDep3 dep3;
public Car1Factory(IDep1 dep1, IDep2 dep2, IDep3 dep3)
{
this.dep1 = dep1 ?? throw new ArgumentNullException(nameof(dep1));
this.dep2 = dep2 ?? throw new ArgumentNullException(nameof(dep2));
this.dep3 = dep3 ?? throw new ArgumentNullException(nameof(dep3));
}
public ICar CreateCar()
{
return new Car1(this.dep1, this.dep2, this.dep3);
}
public bool AppliesTo(Type type)
{
return typeof(Car1).Equals(type);
}
}
public class Car2Factory : ICarFactory
{
private readonly IDep4 dep4;
private readonly IDep5 dep5;
private readonly IDep6 dep6;
public Car2Factory(IDep4 dep4, IDep5 dep5, IDep6 dep6)
{
this.dep4 = dep4 ?? throw new ArgumentNullException(nameof(dep4));
this.dep5 = dep5 ?? throw new ArgumentNullException(nameof(dep5));
this.dep6 = dep6 ?? throw new ArgumentNullException(nameof(dep6));
}
public ICar CreateCar()
{
return new Car2(this.dep4, this.dep5, this.dep6);
}
public bool AppliesTo(Type type)
{
return typeof(Car2).Equals(type);
}
}
Strategy
public class CarStrategy : ICarStrategy
{
private readonly ICarFactory[] carFactories;
public CarStrategy(ICarFactory[] carFactories)
{
this.carFactories = carFactories ?? throw new ArgumentNullException(nameof(carFactories));
}
public ICar CreateCar(Type type)
{
var carFactory = this.carFactories
.FirstOrDefault(factory => factory.AppliesTo(type));
if (carFactory == null)
{
throw new InvalidOperationException($"{type} not registered");
}
return carFactory.CreateCar();
}
}
Usage
// I am showing this in code, but you would normally
// do this with your DI container in your composition
// root, and the instance would be created by injecting
// it somewhere.
var strategy = new CarStrategy(new ICarFactory[] {
new Car1Factory(dep1, dep2, dep3),
new Car2Factory(dep4, dep5, dep6)
});
// And then once it is injected, you would simply do this.
// Note that you could use a magic string or some other
// data type as the parameter if you prefer.
var car1 = strategy.CreateCar(typeof(Car1));
var car2 = strategy.CreateCar(typeof(Car2));
Note that because there is no switch case statement, you can add additional factories to the strategy without changing the design, and each of those factories can have their own dependencies that are injected by the DI container.
var strategy = new CarStrategy(new ICarFactory[] {
new Car1Factory(dep1, dep2, dep3),
new Car2Factory(dep4, dep5, dep6),
new Car3Factory(dep7, dep8, dep9)
});
var car1 = strategy.CreateCar(typeof(Car1));
var car2 = strategy.CreateCar(typeof(Car2));
var car3 = strategy.CreateCar(typeof(Car3));
Answering your comment about code example with Composition Root.
You can create following and this is not a Service Locator.
public class CarFactory
{
private readonly Func<Type, ICar> carFactory;
public CarFactory(Func<Type, ICar> carFactory)
{
this.carFactory = carFactory;
}
public ICar CreateCar(Type carType)
{
return carFactory(carType);
}
and this is how look your Composition Root using Unity DI container :
Func<Type, ICar> carFactoryFunc = type => (ICar)container.Resolve(type);
container.RegisterInstance<CarFactory>(new CarFactory(carFactoryFunc));
I answered a similar question some time ago. Basically it's all about your choice. You have to choose between verbosity (which gives you more help from a compiler) and automation, which allows you to write less code but is more prone to bugs.
This is my answer supporting verbosity.
And this is also a good answer that supports automation.
EDIT
I believe the approach you consider wrong is actually the best. Truth being said, usually there won't so many dependencies in there. I like this approach because it's very explicit and rarely results in runtime errors.
Alternative way 1:
This one is bad. It's actually a service locator, which is considered an anti-pattern.
Alternative way 2
Like you wrote, it's not easy to use if mixed with IOC containter. However in some case a similar approach (poor man's DI) can be useful.
All in all, I wouldn't bother having "many" dependencies in your factories. It's a simple, declarative code. It takes seconds to write and can save you hours of struggling with runtime errors.
I would consider giving the dependencies a good structure so you can utilize something similar to Wiktor's answer, but I would abstract the Car factory itself. Then, you don't use the if..then structure.
public interface ICar
{
string Make { get; set; }
string ModelNumber { get; set; }
IBody Body { get; set; }
//IEngine Engine { get; set; }
//More aspects...etc.
}
public interface IBody
{
//IDoor DoorA { get; set; }
//IDoor DoorB { get; set; }
//etc
}
//Group the various specs
public interface IBodySpecs
{
//int NumberOfDoors { get; set; }
//int NumberOfWindows { get; set; }
//string Color { get; set; }
}
public interface ICarSpecs
{
IBodySpecs BodySpecs { get; set; }
//IEngineSpecs EngineSpecs { get; set; }
//etc.
}
public interface ICarFactory<TCar, TCarSpecs>
where TCar : ICar
where TCarSpecs : ICarSpecs
{
//Async cause everything non-trivial should be IMHO!
Task<TCar> CreateCar(TCarSpecs carSpecs);
//Instead of having dependencies ctor-injected or method-injected
//Now, you aren't dealing with complex overloads
IService1 Service1 { get; set; }
IBuilder1 Builder1 { get; set; }
}
public class BaseCar : ICar
{
public string Make { get; set; }
public string ModelNumber { get; set; }
public IBody Body { get; set; }
//public IEngine Engine { get; set; }
}
public class Van : BaseCar
{
public string VanStyle { get; set; }
//etc.
}
public interface IVanSpecs : ICarSpecs
{
string VanStyle { get; set; }
}
public class VanFactory : ICarFactory<Van, IVanSpecs>
{
//Since you are talking of such a huge number of dependencies,
//it may behoove you to properly categorize if they are car or
//car factory dependencies
//These are injected in the factory itself
public IBuilder1 Builder1 { get; set; }
public IService1 Service1 { get; set; }
public async Task<Van> CreateCar(IVanSpecs carSpecs)
{
var van = new Van()
{
//create the actual implementation here.
};
//await something or other
return van;
}
}
I didn't list it, but you can implement multiple types of cars and their corresponding factories now and use DI to inject whatever you need.
First, you have a concrete factory, an IoC container could be an alternative rather than something to help you there.
Then, just refactor the factory to not to expect a full possible parameter list in the factory constructor. This is the primary issue - why are you passing so many parameters if the factory method doesn't need them?
I would rather pass specific parameters to the factory method
public abstract class CarFactoryParams { }
public class Car1FactoryParams : CarFactoryParams
{
public Car1FactoryParams(Dep1, Dep2, Dep3)
{
this.Dep1 = Dep1;
...
}
public class Car2FactoryParams
...
public class CarFactory
{
public ICar CreateCar( CarFactoryParams params )
{
if ( params is Car1FactoryParams )
{
var cp = (Car1FactoryParams)params;
return new Car1( cp.Dep1, cp.Dep2, ... );
}
...
if ( params is ...
By encapsulating the parameter list in a specific class you just make the client provide exactly these parameters that are required for specific factory method invocation.
Edit:
Unfortunately, it was not clear from your post what are these Dep1, ... and how you use them.
I suggest following approach then that separates the factory provider from actual factory implementation. This approach is known as the Local Factory pattern:
public class CarFactory
{
private static Func<type, ICar> _provider;
public static void SetProvider( Func<type, ICar> provider )
{
_provider = provider;
}
public ICar CreateCar(type)
{
return _provider( type );
}
}
The factory itself doesn't have any implementation, it is here to set the foundation to your domain API, where you want your car instances to be created with this API only.
Then, in the Composition Root (somewhere near the starting point of the app where you configure your actual container), you configure the provider:
CarFactory.SetProvider(
type =>
{
switch ( type )
{
case A:
return _container.Resolve<ICar1>();
case B:
return _container.Resolve<ICar2>();
..
}
);
Note that this example implementation of the factory's provider uses a delegate but an interface could also be used as a specification for an actual provider.
This implementation is basically #1 from your edited question, however, it doesn't have any particular downsides. The client still calls:
var car = new CarFactory().CreareCar( type );
Many DI containers support the notion of named dependencies.
E.g. (Structuremap syntax)
For<ICar>().Use<CarA>().Named("aCar");
Container.GetNamedInstance("aCar") // gives you a CarA instance
If you use something like a convention, a rule how the name is derived from the concrete car type itself, you have a situation where you don't need to touch the factory anymore when you extend the system.
Using this in a factory is straightforward.
class Factory(IContainer c) {
public ICar GetCar(string name) {
Return c.GetNamedInstance(name);
}
}
My main Model Classes are "RoleMaster and "UserMaster"
public class RoleMaster
{
public int RoleId { get; set; }
public string RoleName { get; set; }
}
public class UserMaster
{
public int UserId { get; set; }
public string UserName { get; set; }
}
Here is My main Repository Interface
public interface IRepository<in T> where T : class
{
bool Add(T entity);
}
Implemented Class for RoleMaster
public class RoleRepository : IRepository<RoleMaster>
{
public bool Add(RoleMaster entity)
{
//Add Logic
}
}
Implemented Class for UserMaster
public class UserRepository : IRepository<UserMaster>
{
public bool Add(UserMaster entity)
{
//Add Logic
}
}
Now i want to achieve
container.RegisterType<(IRepository<T>)(new InjectionFactory(m =>
{
if (typeof(T) is RoleMaster)
{
m.Resolve<RoleRepository>();
}
else if (typeof(T) is UserMaster)
{
m.Resolve<UserRepository>();
}
return m;
}));
Is it possible using Unity?
What is the best way to do this kind of conditional Resolve?
You should just register them explicitly with unity
container.RegisterType<IRepository<RoleMaster>, RoleRepository>();
container.RegisterType<IRepository<UserMaster>, UserRepository>();
I would recommend you go with either the generic repository pattern or create a new interface for every repository. Or a combination of the two, but that can get confusing.
With generic repository (there are plenty of examples out there), you would only make one call to the container to register the open generics types as there is only one implementation of the IRepsitory<T> interface...
container.RegisterType(typeof(IRepository<>), typeof(GenericRepository<>));
But if you plan to add custom methods on each repository, you will likely need those methods defined on a custom repository interface for that entity type. Then registration would best be done on the custom repository interface instead of the generic interface...
container.RegisterType<IRepositoryRole, RoleRepository>();
public interface IRepositoryRole : IRepository<RoleMaster>
{
public void DoCustomRoleWork(...) { ... }
}
I am using the Autofac IOC with construcor validation. I can't figure out how to register the classes in the IOC so that LogotypeService gets LogoImageValidator and AdService get AdValidator injected in it's constructors.
I don't want to specify which instance of SomeClass that should be injected.
I have:
One validation interface (IImageValidator)
One base class for the common validation logic (ImageValidatorBase)
Two subclasses which holds specific valiation logic (LogoImageValidator and AdImageValidator)
One service interface (IService)
Two services which each should use different subclasses for validation. (LogotypeService should use LogoImageValidator) and (AdService should use AdValidator)
Interface
public interface IImageValidator
{
bool ValidFileSize();
}
Base class:
public abstract class ImageValidatorBase : IImageValidator
{
//constructor omitted
Public abstract ValidFileSize()
{
//shared code
}
}
Subclass LogoImageValidator
public class LogoImageValidator : ImageValidator
{
//constructor omitted
public override bool ValidFileSize()
{
//class specific code
}
}
Subclass AdImageValidator
public class AdImageValidator : ImageValidator
{
//constructor omitted
public override bool ValidFileSize()
{
//class specific code
}
}
IService
public interface IService{
bool ValidFileSize();
}
LogotypeService
public class LogotypeService : IService
{
private readonly ISomeClass _someClass;
private readonly IImageValidator _imageValidator;
public LogotypeService(ISomeClass someClass, IImageValidator imageValidator)
{
_someClass = someClass;
_imageValidator = imageValidator;
}
public bool ValidFileSize()
{
_imageValidator.ValidFileSize();//use LogoImageValidator subclass here
}
}
AdService
public class AdService : IService
{
private readonly ISomeClass _someClass;
private readonly IImageValidator _imageValidator;
public AdService(ISomeClass someClass, IImageValidator imageValidator)
{
_someClass = someClass;
_imageValidator = imageValidator;
}
public bool ValidFileSize()
{
_imageValidator.ValidFileSize();//use AdValidator subclass here
}
}
Any ideas?
This appears to overlap with this question: Inject Specific Type With Autofac
The answer there suggests that different interfaces be used based on context.
I'm attempting to inject a property using ninject. Given the two bindings in the ninject module below, I would expect the ConcreteDependency to be injected into B. However, it seems that WhenInjectedInto doesn't consider the type being injected into, just the declaring type of the target (property in this case).
Is there a way to achieve the behaviour I expected?
static void Main(string[] args)
{
var kernel = new StandardKernel(new TestModule());
var b = kernel.Get<B>();
var c = kernel.Get<C>();
}
class TestModule : NinjectModule
{
public override void Load()
{
Bind<IDependency>().To<EmptyDependency>();
Bind<IDependency>().To<ConcreteDependency>().WhenInjectedInto<B>();
}
}
abstract class A
{
[Inject]
public IDependency Dependency { get; set; }
}
class B : A {}
class C : A {}
interface IDependency {}
class EmptyDependency : IDependency { }
class ConcreteDependency : IDependency { }
You should use constructor injection instead of property injection if possible. This is a better technique, which is recommended by Mark Seeman, because makes dependencies required for object construction explicit and object signature via constructor is more expressive. Code should look like this:
abstract class A
{
public IDependency Dependency { get; private set; }
public A (IDependency dependency)
{
Dependency = dependency;
}
}
class B : A
{
public B (IDependency dependency)
: base(dependency)
{
}
}
class C : A
{
public C (IDependency dependency)
: base(dependency)
{
}
}
interface IDependency { }
class EmptyDependency : IDependency { }
class ConcreteDependency : IDependency { }
Configuration will be the same as in you example. The following test passes
[Test]
public void TestSpecificBindingToObjectB()
{
var kernel = new StandardKernel(new TestModule());
var b = kernel.Get<B>();
var c = kernel.Get<C>();
Assert.AreNotEqual(b.Dependency.GetType(), c.Dependency.GetType());
Assert.AreEqual(typeof(ConcreteDependency), b.Dependency.GetType());
}
If you have an optional dependency with default implementation and you are ok with decorating your classes with Inject attribute, you can can pull parent information from request, like this:
class TestModule : NinjectModule
{
public override void Load()
{
Bind<IDependency>().To<EmptyDependency>();
Bind<IDependency>().To<ConcreteDependency>().When(req =>req.ParentContext.Request.Service == typeof(B));
}
}
Then the same test given above passes for your class hierarchy with property injection.
In order to check against a concrete type, you can use ParentContext.Plan.Type on the IRequest interface. This should give you the behaviour you expected from WhenInjectedInto. For example:
When(req => req.ParentContext.Plan.Type == typeof(B))