У меня в настоящее время есть набор репозиториев как так
IMyRepository
IAnotherRepository
Они все наследовались IRepository (если это помогает),
Как я могу заставить structuremap использовать сканер IRegistryConvention для регистрации моих конкретных типов, которые называют
SqlMyRepository
SqlAnotherRepository
Я читал эту статью, но она не дала мне достаточно что мне было нужно. AddAllTypesOf зарегистрировал все конкретные типы для IRepositoryInterface, но вместо этого я требую, чтобы каждый конкретный тип регистрировался для интерфейса с эквивалентным именованием. т.е.
For<IMyRepository>().Use<SqlMyRepository>();
Также мне нужно создать несколько именованных экземпляров для тестовых репозиториев.
For<IMyRepository>().Use<TestMyRepository>().Named("Test");
Вот то, что я придумал, и оно работает так, как мне нужно.
public class SqlRepositoryConvention : StructureMap.Graph.IRegistrationConvention
{
public void Process(Type type, Registry registry)
{
// only interested in non abstract concrete types that have a matching named interface and start with Sql
if (type.IsAbstract || !type.IsClass || type.GetInterface(type.Name.Replace("Sql", "I")) == null)
return;
// Get interface and register (can use AddType overload method to create named types
Type interfaceType = type.GetInterface(type.Name.Replace("Sql","I"));
registry.AddType(interfaceType, type);
}
}
И реализовано следующим образом
Scan(cfg =>
{
cfg.TheCallingAssembly();
cfg.Convention<SqlRepositoryConvention>();
});
В частности, эту часть
container = new Container(x =>
{
x.Scan(o =>
{
o.TheCallingAssembly();
o.AddAllTypesOf<IController>().NameBy(type => type.Name.Replace("Controller", ""));
});
});
Так что для вас, я думаю, должно сработать что-то вроде этого
container = new Container(x =>
{
x.Scan(o =>
{
o.TheCallingAssembly();
o.AddAllTypesOf<IRepository>().NameBy(type => type.Name.Replace("I", "Sql"));
});
});