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>();
答案 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的接口名称。