StructureMap3 How to configure constructor string

2019-09-11 05:04发布

问题:

I have registered my types using

Scan(
    scan => {
        scan.TheCallingAssembly();
        scan.WithDefaultConventions();
        scan.With(new ControllerConvention());
    });

But how do I specify for constructor injection with out having to specify the concrete type like this?

string connStr = "...";
For<IRepository().Use<MyRepository>().Ctor<string>("connectionString").Is(connStr);

回答1:

You can create dedicated convention for registration of repositories.

public class RepositoryConvention : IRegistrationConvention
{
    private const string ConnectionString = "your connection string";

    public void Process(Type type, Registry registry)
    {
        if (type.IsConcrete() && type.GetInterfaces().Contains(typeof(IRepository)))
        {
            registry.For(typeof(IRepository))
                .Use(type)
                .CtorDependency<string>("connectionString")
                .Is(ConnectionString);
        }
    }
}

or create dedicated type to provide with connection string. I bet you are getting it from web/app.config so adding abstraction for accessing it would be helpful anyway.

public interface IConfigurationSettingsReader
{
    string ReadConnectionString(string name);
    T ReadSetting<T>(string settingName);
}

Then you just add it as a dependency for your MyRepository and you don't need to add it explicitly in registration or use custom convention.

public class MyRepository : IRepository
{
    private readonly string connectionString;

    public MyRepository(IConfigurationSettingsReader settingsReader)
    {
        this.connectionString = settingsReader.ReadConnectionString("ConnStrName");
    }
}

You can consider creating an abstract base repository class to be inherited by each repository to get rid of setup bolerplate.

Hope this helps!