Search code examples
c#.netdependency-injectionattributesdryioc

Define primitive resolve-time values in attribute on constructor parameter in DryIoC


In my code there's a dependency (MyDependency) that I want to be resolved in a class (MyClass). The dependency has a few dependencies itself as well as a primitive constructor parameter (primValue), that should be defined by the resolving class. There are other classes besides MyClass that also depend on MyDependency, but they all use different values for primValue.

public class MyDependency : ISpecificDependency
{
    public Dependency(IDependencyA depA, IDependencyB depB, int primValue)
    {
        /*...*/

        this.primValue = primValue;
    }
}

public class MyClass
{
    public MyClass(IDependencyC depC, IDependencyD depD, ISpecificDependency specDep)
    {
        /*...*/

        this.specDep = specDep;
    }
}

I know a way to do this would be to change the constructor of MyClass as following, but that is pretty ugly because I try to inject the container itself as rarely as possible:

public MyClass(IDependencyC depC, IDependencyD depD, IContainer container)
{
    /*...*/

    this.specDep = container.Resolve<ISpecificDependency>(args: new object[] { 123 });
}

But my question is, if something like this could maybe also be achieved by using attributes. What I'm thinking of would be something similar to this:

public MyClass(IDependencyC depC, IDependencyD depD, [DependencyArguments(123)] ISpecificDependency specDep)
{
    /*...*/

    this.specDep = specDep;
}

Is something like that possible?


Solution

  • There are a couple of ways to provide the primitive value on resolution:

    1. Via Func<MyPrimitiveType, MyService>: container.Resolve<Func<int, MyClass>>()(123)
    2. Via global rule container = container.WithDependencies(Parameters.Of.Type<int>(req => req.Parent.Any(p => p.ImplementationType == typeof(MyClass)) ? 123 : 42))

    There are also a number of ways to specify the value on registration.