I seem to be stumped on how to implemented the strategy pattern with a DI container.
I have a strategy interface:
public interface IUserCompaniesInviteStrategy
{
bool InviteUserToCompany(UserCompaniesInviteRequest userCompaniesInviteRequest);
}
and a couple of concrete classes:
public class ConcreteExistingUserInviteStrategy : IUserCompaniesInviteStrategy
public class ConcreteNewUserInviteStrategy : IUserCompaniesInviteStrategy
How do I wire up Unity with this?
container.RegisterType<IUserCompaniesInviteStrategy, ConcreteExistingUserInviteStrategy>();
container.RegisterType<IUserCompaniesInviteStrategy, ConcreteNewUserInviteStrategy>();
obviously doesn't work...
I tried:
container.RegisterType<IUserCompaniesInviteStrategy<ConcreteExistingUserInviteStrategy>, ConcreteExistingUserInviteStrategy>();
container.RegisterType<IUserCompaniesInviteStrategy<ConcreteNewUserInviteStrategy>, ConcreteNewUserInviteStrategy>();
with
public interface IUserCompaniesInviteStrategy<T>
That doesn't seem to work.
I think what I'd like to do here is use named types, so like:
container.RegisterType<IUserCompaniesInviteStrategy, ConcreteExistingUserInviteStrategy>("1");
container.RegisterType<IUserCompaniesInviteStrategy, ConcreteNewUserInviteStrategy>("2");
However, I have constructor injection setup and using container.resolve isn't a good option for me because of n-tier architecture and chaining dependencies I'd have to resolve.
How can I inject a named type into a constructor? Is there a better way to do what I'm trying to do? (Create an interface that resolves to two concrete strategies)
Update:
I took a look at With Unity how do I inject a named dependency into a constructor? . The accepted answer won't work because I don't have a dependency on Unity in my domain, nor do I want it. I tried the StrategyResolver, but I'm getting:
An error occurred when trying to create a controller of type 'UserController'. Make sure that the controller has a parameterless public constructor.
That is indicative of a DI problem.
The StrategyResolver and IStrategyResolver are the same as in the example:
public class StrategyResolver : IStrategyResolver
{
private IUnityContainer container;
public StrategyResolver(IUnityContainer unityContainer)
{
this.container = unityContainer;
}
public T Resolve<T>(string namedStrategy)
{
return this.container.Resolve<T>(namedStrategy);
}
}
public interface IStrategyResolver
{
T Resolve<T>(string namedStrategy);
}
My config:
container.RegisterType<IUserCompaniesInviteStrategy, ConcreteExistingUserInviteStrategy>("ExistingUser");
container.RegisterType<IUserCompaniesInviteStrategy, ConcreteNewUserInviteStrategy>("NewUser");
container.RegisterType<IStrategyResolver, StrategyResolver>();
container.RegisterType<IUserFactory, UserFactory>();
Concretes:
public class ConcreteExistingUserInviteStrategy : IUserCompaniesInviteStrategy
public class ConcreteNewUserInviteStrategy : IUserCompaniesInviteStrategy
And then I call it like:
_strategyResolver.Resolve<IUserCompaniesInviteStrategy>("ExistingUser");
Not sure what's wrong with it.
Related
I have lack of understanding in this basic concept of OOP. Here is an example:
Say I have a base repository which is derived by 3 different classes. The base class requires the dbContext in the constructor , injected by dependency injection. Because of this the child classes have to pass the dbContext every time I instantiate them. The requirement is simple: The base class should instantiate the Context for the child classes. Is that possible? I do not want the child classes to worry about the context. I just want them to call it.
Here is my base class.
public class CastingBaseRepository<TEntity> : ICastingBaseRepository<TEntity> where TEntity : class, IEntity
{
private readonly CastingContext _context;
public CastingBaseRepository(CastingContext context) => _context = context ?? throw new ArgumentNullException(nameof(context));
// Context property
public CastingContext Context => _context;
}
Heres how the child class would be:
public class CommercialJobsRepository : CastingBaseRepository<Audition>, ICommercialJobsRepository
{
/* I do not want to use base(context) here. I need a way for this class to just call Context property from the derived class.. Possible? */
private CastingContext _context;
public CommercialJobsRepository(CastingContext context) : base(context)
{
_context = context;
}
public async Task<IList<OpenJobs>> GetOpenJobs()
{
// test code
var tt = await _context.Audition.Take(10).ToListAsync();
return new List<OpenJobs>();
}
}
Here is my context class
public partial class CastingContext : DbContext
{
public virtual DbSet<Audition> Audition { get; set; }
public CastingContext(DbContextOptions<CastingContext> options) : base(options)
{
}
}
And here is the startup.cs
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// DB Context
services.AddDbContextPool<CastingContext>(options => { options.EnableSensitiveDataLogging(); options.UseSqlServer(Configuration.GetConnectionString("dbCast")); });
}
}
I am using strategy pattern to determine which child class would be accessed at runtime. That too needs to have CastingContext injected the constructor which is again ugly. The point is, there should be only one class exposing the context to all derived classes or perhaps through a static method. Can you please help me understand how to do it?
Here is my Strategy class:
public class JobsStrategyContext
{
private readonly CastingContext _context;
private readonly Dictionary<eBreakdownTypes, IJobsRepository> Strategies =
new Dictionary<eBreakdownTypes, IJobsRepository>();
public JobsStrategyContext(CastingContext context)
{
_context = context;
Strategies.Add(eBreakdownTypes.Ftv, new FtvJobsRepository(_context));
Strategies.Add(eBreakdownTypes.Commercial, new CommercialJobsRepository(_context));
Strategies.Add(eBreakdownTypes.Theatre, new TheatreJobsRepository(_context));
}
public async Task<IList<OpenJobs>> GetOpenJobsBySubType(eBreakdownTypes breakdownType)
{
return await Strategies[breakdownType].GetOpenJobs();
}
}
No, you cannot both at the same time use dependency injection and hardcode the instantiation of your dependency in the base class. If you want to inject the dependency from an external consumer, it needs to pass through the derived constructor.
At best, you can pass a service locator which the base constructor then uses to fetch the dbcontext, but then you're still handling the service locator in the derived class. But service locators are no longer considered good practice because they have notable drawbacks such as decreasing readability/usability and becoming a general nuisance to handle in sufficiently large codebases.
While it would technically achieve what you want to achieve, don't start using static service locators. The costs far outweigh the benefits.
However, the problem outset doesn't quite make sense to me. If you're using dependency injection, I would assume you're using some sort of automated injection where you don't have to manually instantiate all dependencies.
Yes, you still need to mention the dbcontext as a (derived and base) constructor parameter, but your derived classes don't need to handle it (other than passing it to the base constructor. The effort to do so is minimal and it allows for maximum freedom in terms of dependency injection.
This is how inheritance works by design.
This is a functional limitation of C# as a language. You don't have to provide the same constructor(s) in child classes as you have in the base class, but you must satisfy those constructors in the base class. For example:
public class BaseClass
{
public BaseClass(Dependency dep) {}
}
public class ChildClass
{
public ChildClass(Dependency dep) : base(dep) {}
}
Or:
public class ChildClass
{
public ChildClass() : base(new Dependency()) {}
}
In either case, you somehow, someway must provide the Dependency instance to the base class constructor, but you may opt to not actually construct the child class with that dependency, and instead, get it internally.
However, in practical terms with something like DbContext which relies itself on dependencies being injected, it's going to require carrying that dependency all the way through: your child class will need a constructor where it can be injected in order to then pass down into the base class constructor.
You have to provide the dependency through the child class because, When you are creating an instance of the child class, the base class is also getting constructed and hence the dependencies must be supplied.
Of course for the ease of coding and managing these dependencies,you can use Use the IoC containers like Unity to handle the automatic dependency injections (The Unity Application dependency injection container with support for constructor, property, and method call injection)
I'd like my app to be not strictly tied to an IOC, so basically my application should need to call an IOC factory pattern that solve the specific implementation on runtime.
So, first off I've created my interface:
IIOCService
interface IIOCService
{
void RegisterSingleton<RegisterType>()
where RegisterType : class;
void RegisterMultiple<RegisterType>()
where RegisterType : class;
void RegisterMultiple<RegisterType>(IEnumerable<Type> implementationTypes);
// and so on
}
then an implementation of IIOCService, using TinyIOC
class TinyIOCServiceImpl : IIOCService
{
private static readonly TinyIOCServiceImpl _Current = new TinyIOCServiceImpl();
public static TinyIOCServiceImpl Current
{
get
{
return _Current;
}
}
TinyIoC.TinyIoCContainer container;
public TinyIOCServiceImpl()
{
container = TinyIoC.TinyIoCContainer.Current;
}
public void RegisterSingleton<RegisterType>()
where RegisterType : class
{
container.Register(typeof(RegisterType)).AsSingleton();
}
// ...and so on
}
For the class that decides to resolve the implementation of the IOC container, I've created an IOCFactory
IOCFactory
class IOCFactory
{
public enum IOC { TinyIOC }
public IIOCService GetService(IOC iocType)
{
switch (iocType)
{
case IOC.TinyIOC:
return TinyIOCServiceImpl.Current;
default:
throw new NotSupportedException();
}
}
}
Now my question is:
Should I need to reinstantiate the factory for every class where IOC is needed or there is some more elegant way?
IIOCService iocService = new IOCFactory().GetService(IOCFactory.IOC.TinyIOC);
// code needed everytime I need to use IOC (i.e. ServiceLocator, ViewModelLocator, etc.)
// is this code a bit redundant ???
I agree that creating a wrapper around your IOC container is a bit redundant. But, if you need to call your IOC container to resolve a specific, on run-time determined, instance of an interface, you can create a resloving interface (not with the factory pattern, but staying within the IOC pattern). Something like this (this is too basic, just so you can get the idea):
public interface IResolve {
public T Resolve<T>();
}
You can create an implementation for this specific interface and expose it to your IOC container. There is no issue doing this in a single instance pattern.
When you need to resolve something in a class that was resolved by the IOC container, just add the IResolve to your constructor and you can address the IOC container without a dependency on whatever brand of IOC container is used.
I hope this brought some clarity for you?
Let's say in C# I have a class called A
public class A : IInterfaceA
{
[Dependency]
B _b;
}
Then in B class I have a constructor like this:
public class B
{
...
public B(string someParam) { ... }
...
}
Now, I register class A like this:
_unityContainer.RegisterType<IInterfaceA, A>("RegistrationA");
and to resolve the interface I do:
_unityContainer.Resolve<IInterfaceA>("RegistrationA", new ParameterOverride("someParam", "The param."));
Now I want to know if it is good practice to resolve the class and pass the parameters like this or I should do it another way.
Thanks a lot :)
First of all the code you posted does not work: in fact you're overriding the parameter of class A, while in your code the constructor with the parameter is B.
Generally speaking, using parameter override is not a good practice in my opinion (unless some very specifical context like a console application or a web service using an existing container but it's avoidable in most cases) for these reason:
Using Resolve looks like a Service locator: anti-pattern nowadays. You will find a lot of discussion googling about.
Using ParameterOverride means that the client (the caller of Resolve) knows exactly the type mapped in the container and wants that type initialized with a specific parameter. But this is just the opposite of inversion of control.
The best way is to use an abstract factory. You can add in your code and use a more flexible and SOLID abstract factory:
public interface BFactory {
B Create(string bparam);
}
public class BFactoryUnity : BFactory {
private IUnityContainer container;
public BFactoryUnity(IUnityContainer container) {
this.container = container;
}
public B Create(String bParam) {
var b = new B(bParam);
container.BuildUp(b);
return b;
}
}
So you can register:
_unityContainer.RegisterType<IInterfaceA, A>("RegistrationA")
.RegisterType<BFactory, BFactoryUnity>();
Now the client can resolve only the factory and use it:
var bFactory = _container.Resolve<BFactory>();
var b = bFactory.Create();
Now, in a big application you will need a lot of similar factories. To avoid the boilerplate code of abstract factories and implementations you can find in the web some implementation of automatic abstract factory extensions.
I have two classes, one which sets up the container by registering types and one which contains a static property which I want to inject into. My issue is the property is never set by injection so when I call a method on it, the property is always null.
public class ClassOne
{
public void Method()
{
Container.RegisterType<IClass, ClassImplOne>("ImplOne");
Container.RegisterType<IClass, ClassImplTwo>("ImplTwo");
}
}
public static class ClassTwo
{
[Dependency]
public static IClass SomeProperty { get; set; }
public static void SomeOtherMethod()
{
SomeProperty.AnotherMethod();
}
}
If I remove the Dependency attribute and in ClassOne do a simple
ClassTwo.SomeProperty = Container.Resolve<IClass>("ImplOne");
it works fine, but I want to know if it is possible to do this without explicitly assigning a value to the property (i.e. can the container inject through attributes)?
Edit:
Thanks. I have removed the static declaration from ClassTwo and in ClassOne added RegisterType and Resolve for ClassTwo and also added InjectionProperty:
Container.RegisterType<IClass, ClassImplOne>("ImplOne", new InjectionProperty("SomeProperty"));
but it still does not work :S
Edited after considering comments:
There are a variety of reasons why at times you still want or need to use static classes instead of cascading everything through Unity.
If the static class has a dependency on another class that you would want to be configurable/exchangeable via your Unity configuration I prefer using a factory pattern as described at How to resolve dependency in static class with Unity? or simply assigning a function to resolve the dependency when needed, rather than referencing the Container from within the static class. One advantage being that all your Unity configuration can be in the same place.
In your case it could look like this:
public static class ClassTwo
{
private static IClass _someProperty;
public static Func<IClass> ResolveProperty { private get; set; }
private static IClass SomeProperty
{
get { return _someProperty ?? (_someProperty = ResolveProperty()); }
}
public static void SomeOtherMethod()
{
SomeProperty.AnotherMethod();
}
}
And in your Unity configuration add this:
ClassTwo.ResolveProperty = () => container.Resolve<IClass>();
Unity inject dependencies when the class is resolved through Unity. A static class can not be created, so Unity can not inject dependencies.
Instead of having a Static class, use Unity to resolve a pseudo-singleton class (ContainerControlledLifetimeManager) of ClassTwo. This way Unity injects IClass to ClassTwo when ClassTwo is created (resolved throug Unity container) and, as is configured as singleton, you always have the same instace of ClassTwo in the whole lifecicle of your application.
You must resolve ClassTwo through Unity.
Container.RegisterType<IClass, ClassImplOne>("ImplOne");
Container.RegisterType<IClass, ClassImplTwo>("ImplTwo");
Container.RegisterType<InterfaceImplemetedByClassTwo, ClassTwo>();
//Simple example. Don't forget to use ContainerControlledLifetimeManager for ClassTwo to simulate sigleton.
And when you need ClassTwo:
Container.Resolve<InterfaceImplemetedByClassTwo>
Having the config in ClassTwo:
public class ClassTwo : InterfaceImplemetedByClassTwo
{
[Dependency("ImplOne")] //inject ClassImplOne
public IClass SomeProperty { get; set; }
BUT this is not a great solution, I think your problem is with the phylosophy of DI. You need to cascade dependencies from the top layer classes of your app. Resolve the top layer classes in a explicit way. (Container.Resolve) and dependecies injection cascade down thanks to the magic of Unity. When 2 classes (top layer or not) need to use the same instance of ClassTwo Unity do the dirty work if you configured ClassTwo with ContainerControlledLifetimeManager.
In other words, you don't need static class, you inject the same instance of a class in other classes than need it.
I currently have a main class which might call another class which might call 2 or 3 others. The main class might create a Windows form as well.
So at the moment we might have:
public class MainClass
{
...
AnotherClass = new AnotherClass();
fmMain myForm = new fmMain();
}
public class AnotherClass
{
...
DatabaseClass dbClass = new DatabaseClass();
FileClass fClass = new FileClass();
}
As I see it, after refactoring and putting in constructor interface dependencies I can use an IOC container.
The problem is my entry point is the main class so all I can see to do is have all the dependencies in the main class constructor and then pass these down into the other classes and forms.
The issue is this could get very messy and the main class might have 10 dependencies most of which used in other classes. Is there an alternative?
Let the IoC container to do this.
Register AnotherClass as a dependency and then resolve it directly referring to container instance.
Dependencies should be defined locally to where they are required i.e. the dependencies should be defined on the constructors of the types, then use an IoC container to resolve all types. In this way the IoC takes care of "passing these down into the other classes and forms". When using an IoC container avoid using "new" whenever possible, and instead use the container to create instances. It will handle creation and injection of dependencies for you.
For example (using Ninject), the following demonstrates a Form which defines its own dependencies. The container will supply and inject all dependencies recursively when used to resolve an instance of the ProductForm.
Dependencies do not need to be injected into the entry-point class, but are specified as bindings in a module and then injected by the container when types such as Forms are resolved.
public class Program
{
public Program()
{
IKernel kernel = new StandardKernel(new MainModule());
Form form = kernel.Get<ProductForm>();
form.Show();
}
}
public class MainModule : NinjectModule
{
public override void Load()
{
Bind<ProductForm>().ToSelf();
Bind<IProductService>().To<ProductService>();
Bind<IProductDb>().To<IProductDb>();
}
}
internal class ProductForm : Form
{
private readonly IProductService _productService;
public ProductForm(IProductService productService)
{
_productService = productService;
}
}
internal interface IProductService {}
internal class ProductService : IProductService
{
private readonly IProductDb _productDb;
public ProductService(IProductDb productDb)
{
_productDb = productDb;
}
}
internal interface IProductDb {}
internal class ProductDb : IProductDb {}
It sounds like your Main class is your Composition Root. That's fine - it's not going to become messy if that's the only thing it does. This should be its single responsibility. In other words: your application entry point should be a Humble Object.