Преобразование из Виндзорского замка в StructureMap в проекте MVC2 - PullRequest
0 голосов
/ 07 мая 2010

Я узнаю о лучших практиках в 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 ()?

Ответы [ 2 ]

1 голос
/ 10 мая 2010

Почувствую себя грязным, отвечая на свой вопрос, но я сделал следующее:

public class ControllerRegistrar : IComponentRegistrar
    {
        public void Register(IContainer container)
        {
            container.Configure(x =>
            {
                x.Scan(scanner =>
                {
                    scanner.Assembly(Assembly.GetExecutingAssembly());
                    scanner.AddAllTypesOf<IController>().NameBy(type => type.Name.Replace("Controller", ""));
                });
            });

        }
    }

Я не уверен на 100%, что это правильно, но это работает. Вытащил его в основном из раздела «Регистрация типов по имени» этой страницы документации StructureMap .

1 голос
/ 07 мая 2010

Посмотрите на реестры StructureMap (http://structuremap.github.com/structuremap/RegistryDSL.htm).. Для управления жизненным циклом используйте что-то вроде:

For<ISomething>().Use<Something>().LifecycleIs(new SingletonLifecycle());

(по умолчанию это переходный процесс).

Когда вы загружаетеКонтейнер можно сказать:

ObjectFactory.Initialize(c => c.Scan(s => {
    s.WithDefaultConventions();
    s.LookForRegistries();
}
...