Define default constructor with StructureMap witho

2019-06-01 21:03发布

I've been using StructureMap for sometime now but I'm far from an expert. My problem is simple, I'm trying to configure SM via code (Registry) to use a particular constructor when creating an instance of a repository object.

Here are my 2 constructors (note neither is the greediest).

public BusinessUnitRepository( IDatabase database )
    : base( database ) {

}

public BusinessUnitRepository( IDatabaseFactory factory )
    : base( factory ) {

}

Note: The first constructor takes an instance of the IDatabase interface and is called by the base class's ctor(IDatabaseFactory) implementation.

What I'm trying to do is configure SM to use the second constructor and provide an instance of DatabaseFactory from the SM container. I can't use the [DefaultConstructor] attribute in the assembly where BusinessUnitRepository is defined so this option is off the table.

My Registry code

ForRequestedType<IDatabaseFactory>()
    .CacheBy( InstanceScope.PerRequest )
    .TheDefaultIsConcreteType<DatabaseFactory>();


ForRequestedType<Repository.IBusinessUnitRepository>()
    .CacheBy( InstanceScope.PerRequest )
    .TheDefault.Is.OfConcreteType<BusinessUnitRepository>().CtorDependency<IDatabaseFactory>().Is<DatabaseFactory>();

When I run the program SM throws a 302 error when trying to create an instance of BusinessUnitRepository.

StructureMap.StructureMapException: StructureMap Exception Code:  302
There is no argument of type Repository.LinqToSql.IDatabaseFactory for concrete type Repository.LinqToSql.BusinessUnitRepository

FYI:

  • If I do reference StructureMap in the Repository.LinqToSql.BusinessUnitRepository assembly and use the [DefaultConstructor] attribute on my IDatabaseFactory constructor everything works perfectly.
  • Also I have confirmed that StructureMap does contain a configured 'Repository.LinqToSql.DatabaseFactory'

1条回答
叛逆
2楼-- · 2019-06-01 21:33

I found a solution but the 'magic' has a stink:

ForRequestedType<Repository.IBusinessUnitRepository>()
            .CacheBy( InstanceScope.PerRequest )
            .TheDefault.Is.OfConcreteType<BusinessUnitRepository>()
            .CtorDependency<IDatabaseFactory>("factory").IsTheDefault();

SelectConstructor<BusinessUnitRepository>( () => new BusinessUnitRepository((IDatabaseFactory)null ) );

I still think there is a better answer. Since I have quite a few Repository interfaces and concrete implementation it seems like a lot of work to define the SelectConstructor for each type. I'm open to suggestions.

查看更多
登录 后发表回答