如何使用带有StructureMap映射的IRepository <t>的约定</t>

时间:2011-06-30 14:34:43

标签: structuremap

StructureMap中有没有办法用一行或约定来做这种重复映射?

    For<IRepository<Mailout>>().Use<MailoutRepository>();
    For<IRepository<MailServer>>().Use<MailServerRepository>();
    For<IRepository<MailoutStatus>>().Use<MailoutStatusRepository>();
    For<IRepository<MailoutTemplate>>().Use<MailoutTemplateRepository>();
    For<IRepository<Publication>>().Use<PublicationRepository>();
    For<IRepository<Recipient>>().Use<RecipientRepository>();

4 个答案:

答案 0 :(得分:5)

要将IRepository<Mailout>映射到MailoutRepository,请使用:

var c = new Container(x =>
{
    x.Scan(scan =>
    {
        // there are other options to expand which assemblies to scan for types
        scan.TheCallingAssembly(); 
        scan.ConnectImplementationsToTypesClosing(typeof (IRepository<>));
    });
});

要将IRepository<Mailout>映射到Repository<Mailout>,请使用:

var c = new Container(x =>
{
    x.For(typeof (IRepository<>)).Use(typeof (Repository<>));
});

答案 1 :(得分:0)

您可以使用Repository base:

public class RepositoryBase<T> : IRepository<T> where T : Entity

然后有这样的事情:

public class UserRepository : RepositoryBase<User>, IUserRepository
public class OtherRepository : RepositoryBase<Other>, IOtherRepository

您的存储库接口会阻止通用存储库接口:

public interface IUserRepository : IRepository<User>
public interface IOtherRepository : IRepository<Other>

然后你就可以这样注册:

For(typeof (IRepository<>)).Use(typeof (RepositoryBase<>));

它对我有用。

答案 2 :(得分:0)

这是一种解决方法,因为我们找不到任何更短的映射方式。

首先,映射到一个开放的通用实现类,如discussed elsewhere

For(typeof(IRepository<>)).Use(typeof(ConcreteRepository<>));

然后,对于具有自定义行为的每个存储库,在适当的接口上添加扩展方法。例如,假设您的MailoutStatusRepository有方法GetStatus(),您可以将其转换为IRepository<MailoutStatusRepository>上的扩展方法:

public static Status GetStatus(this IRepository<MailoutStatusRepository> repo,
                               Mailout mail)
{
    return mail.Status;  // or whatever
}

现在您拥有自定义存储库行为,而无需担心将StructureMap的输出强制转换为某个自定义类:

var repo = container.GetInstance<IRepository<MailoutStatusRepository>>();
var status = repo.GetStatus(mailout);

此方法的另一个好处是,无论您的存储库实现如何,您的自定义存储库行为都会起作用:在测试和生产代码中。唯一的缺点(我认为)是你的存储库必然是无状态的,但我们还没有发现这是一个问题。

答案 3 :(得分:0)

Scan(x =>
{
    x.WithDefaultConventions();
    x.AssemblyContainingType(typeof(UserRepository));
    x.AddAllTypesOf(typeof(Repository<>));
    x.ConnectImplementationsToTypesClosing(typeof(IRepository<>));
});

WithDefaultConventions是显示代码的重要部分,因为使用此设置,您可以说StructureMap使用将IUserRepository映射到UserRepository的约定。因此,StructureMap假定该类被命名为没有前缀I的接口名称。