2

I am trying to register objects to the DryIoc container using a factory.

void Main()
{
    var container = new Container();
    container.Register<IFactory, Factory>();
    container.Register<IService>(
        made: Made.Of(r => ServiceInfo.Of<IFactory>(), f => f.Create("default")));

    container.Resolve<IService>().Dump();
    container.Resolve<IService>("name1").Dump();
    container.Resolve<IService>("name2").Dump();
}

public interface IFactory
{
    IService Create(string name);
}

public class Factory : IFactory
{
    public IService Create(string name) => new Service(name);
}

public interface IService
{
    string Name { get; }
}

public class Service : IService
{
    public Service(string name) => Name = name;
    public string Name { get; }
}

I want the policy used during resolution to be the parameter passed into the factory method. In the code above I have hardcoded this parameter to "name", but I would like for policy used to be used instead. Specifically, in the 2nd and 3rd call to Resolve, the parameter to be passed into the factory method should be name1 and name2 respectively.

The 3 calls to resolve only succeeds for the first call, the other two fail because there is no registration in the container with a policy name1 or name2. Now, I know that policies can be all types of objects, not just strings, but even so I would like for this to work for my case.

So is there any way to tweak the registration call to take the policy and inject it into the factory method:

container.Register<IService>(
    made: Made.Of(r => ServiceInfo.Of<IFactory>(), f => f.Create(<what to put here>)));
                                                                         ^
                                                                         |
...                            +-----------------------------------------+
                               |
container.Resolve<IService>("name1");

I've looked over the namespace where I have Arg.Of and ServiceInfo.Of, but there doesn't seem to be anything that indicate that it might be of use.

Note that a valid answer for this question might even be "This is not possible". It might be that there is no way to do what I'm asking, and that there really has to be multiple registrations, one for each policy to use.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825

1 Answers1

1

If by "policy" you mean passing a serviceKey as an argument to factory method, you can do this.

You need an Arg.Index(int) to specify a custom argument to factory method:

It may look like this:

container.Register<IService>( made: Made.Of(r => ServiceInfo.Of<IFactory>(), 
    f => f.Create(Arg.Index(0)),
    r => r.ServiceKey)); 

Arg.Index(0) works similar to {0} placeholder in string.Format, where you specify an actual arguments after format string. Here is the same, but arguments may depend on request.

Sorry, if it not compiles right away, did not have an access to laptop to verify.

dadhi
  • 4,807
  • 19
  • 25