Roman
Roman

Reputation: 10403

How to pass dynamic arguments to Structuremap when constructing a new type?

There are cases in my app where my repositories require passing different arguments to constructors of the concrete types. I want to be able to do something like this:

var arg = (x == y) ? z : a;
ObjectFactory.GetInstance<IRepository>(arg);

Where the argument can only be constructed at the time of creating the Repository instance depending on some condition.

How can this be done?

Upvotes: 4

Views: 1844

Answers (3)

PHeiberg
PHeiberg

Reputation: 29811

As @Steven also says, I think that if possible you should let the class that needs the dependency (that has a dynamic argument) take a factory as a parameter so that you can control the creation from the consumer.

With structure map there is built in support for this so that you don't have build a factory class.

Let the consumer take a Func as a ctor argument and create the repository (dependency) by invoking the Func with the argument:

public class Consumer
{
    public Consumer(Func<ArgumentType, IRepository> repositoryFactory)
    {
      _repositoryFactory = repositoryFactory;
    }

    public void CallRepository()
    {
       ArgumentType arg = (x == y) ? z : a;
       var repository = _repositoryFactory(arg);
       repository.GetById(...);
    }
}

In the configuration for structure map, you can configure the func:

For<Func<ArgumentType, IRepository>>().Use( arg => new Repository(arg));

Upvotes: 7

Steven
Steven

Reputation: 172616

Create an IRepositoryFactory and register and resolve that instead of resolving the IRepository. This will save you from having to call the container directly from within your application. That should be prevented at all cost.

Upvotes: 1

gram
gram

Reputation: 2782

I think something like this should work:

var arg = (x == y) ? z : a;
ObjectFactory.With("argumentName").EqualTo(arg).GetInstance<IRepository>();

Upvotes: 1

Related Questions