I am not sure what is the exact name for this pattern (probably Factory Method), but I often have a situation where I have to select a specific derived type based on some parameters.

For example, I may have a SyncFactory with CreateSync method that creates a Sync based on number of parameters.

public class SyncFactory {
    public ISync CreateSync(…) {
        if (…)
            return new FullSync(…);

        if (…)
            return new ExportSync(…);
        
        return new SimpleSync(…);
    }
}

This is a simplest situation. Now a realistic case may require synс operations to depend on some services.

Ok, let’s put them into a DI container and resolve them:

public class SyncFactory {
    // IResolver abstracts specific DI implementation
    // and the fact we are using DI. It is also mockable.
    public SyncFactory(IResolver<ISync> resolver) { … } 

    public ISync CreateSync(…) {
        if (…)
            return resolver.Resolve<FullSync>();

        if (…)
            return resolver.Resolve<ExportSync>();
        
        return resolver.Resolve<SimpleSync>();
    }
}

Up to now everything went quite smooth. But what if the factory needs to give some additional parameters to the syncs, like some SyncEndPoint?

With this in mind, I immediately stumble into two problems. First one is practical: how to pass parameters to the component being resolved? Second one is perfectionist: if components make no sense without these additional parameters, why should they be registered and available in a DI container?

I have been working with Castle IoC framework and I have found no good solution to both of these problems. First one can be solved by passing “additionalArguments” to Resolve methods, but this couples me to parameter names.

What I would like to do is to have some kind of local scope so I could do the following:

public class SyncFactory {
    public ISync CreateSync(…) {
        using (var endPoint = this.CreateEndPoint(…)) 
        using (var scope = new ComponentScope(endPoint)) {
            if (…)
                return resolver.Resolve<FullSync>();

            if (…)
                return resolver.Resolve<ExportSync>();
        
            return resolver.Resolve<SimpleSync>();
        }
    }
}

For second one, it makes sense to have a Create<T>() method on the container that does not require T to be registered, but does the same constructor discovery/creation as it does for registered components. Otherwise, we have to register useless components in the container, which leads to container pollution.

Unfortunately, Windsor/MicroKernel does not have this feature.

I am still not sure whether it’s me doing something the wrong way or argument coupling and container pollution are considered not that big of a deal. For me they seem to be a good feature test for DI Framework, and I am yet to see one with these fixed.