Я узнаю о лучших практиках в MVC2 и выбиваю копию проекта «Кто может мне помочь» (http://whocanhelpme.codeplex.com/) от Codeplex. В нем они используют Castle Windsor для своего контейнера DI. Один Задача «обучения», которую я пытаюсь выполнить, - преобразовать эту подсистему в этом проекте для использования StructureMap.
По сути, в Application_Start () код сообщает о контейнере Windsor. Затем он проходит через несколько сборок, используя MEF, в ComponentRegistrar.cs:
public static class ComponentRegistrar
{
public static void Register(IContainer container)
{
var catalog = new CatalogBuilder()
.ForAssembly(typeof(IComponentRegistrarMarker).Assembly)
.ForMvcAssembly(Assembly.GetExecutingAssembly())
.ForMvcAssembliesInDirectory(HttpRuntime.BinDirectory, "CPOP*.dll") // Won't work in Partial trust
.Build();
var compositionContainer = new CompositionContainer(catalog);
compositionContainer
.GetExports<IComponentRegistrar>()
.Each(e => e.Value.Register(container));
}
}
и любой класс в любой сборке, которая имеет интерфейс IComponentRegistrar, запустит свой метод Register ().
Например, реализация метода Register () контроллера регистратора в основном выглядит так:
public void Register(IContainer container)
{
Assembly.GetAssembly(typeof(ControllersRegistrarMarker)).GetExportedTypes()
.Where(IsController)
.Each(type => container.AddComponentLifeStyle(
type.Name.ToLower(),
type,
LifestyleType.Transient ));
}
private static bool IsController(Type type)
{
return typeof(IController).IsAssignableFrom(type);
}
Надеюсь, я не слишком много убиваю WCHM. Мне интересно, как это сделать с StructureMap? Я предполагаю, что я использую Configure (), так как Initialize () сбрасывает контейнер при каждом вызове? Или синица - это совершенно другой подход? Нужно ли мне сканирование сборок на основе MEF, используемое для поиска всех регистраторов и запуска каждого из них Register (), или есть что-то похожее в функции StructureMap Scan ()?