Единство: что и когда регистрировать - PullRequest
1 голос
/ 04 ноября 2010

Моя текущая реализация некоторого веб-приложения ASP.NET регистрирует все классы репозитория и некоторые вспомогательные классы обслуживания в моей оболочке вокруг контейнера для единства:

public class MyUnityContainer : UnityContainer
{
    public MyUnityContainer ()
    {
        string strConnectionString = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
        _context = new MyDataClassesDataContext(strConnectionString);

        this
            .RegisterInstance(typeof(CMCoreDataClassesDataContext), _context, new ContainerControlledLifetimeManager())
            ;

        //  Register Repository classes
        this
            .RegisterType<IBlockedRegistrationRepository, BlockedRegistrationRepository>()
            .RegisterType<ICmOptionRepository, CmOptionRepository>()
            .RegisterType<ICommandExecutionLogRepository, CommandExecutionLogRepository>()
        ...
    }

    public static T GetContainer<T>(IDictionary items) where T : class, IUnityContainer, new()
    {
        T container;
        lock (Lock)
        {
            if (items.Contains(UnityKey) == false)
            {
                container = new T();
                items.Add(UnityKey, container);
            }
            else
            {
                container = items[UnityKey] as T;
            }
        }

        return container;
    }

Вот пример того, как создается экземпляр контейнера (я создаюновый экземпляр контейнера для каждого запроса, но только один экземпляр для каждого запроса):

        using (IUnityContainer container = MyUnityContainer.GetContainer<McaUnityContainer>(HttpContext.Current.Items))
        { ... }

Все работает отлично, но одна вещь меня смущает: теперь у меня зарегистрировано почти 50 классов каждыйвремя создания контейнера.Не все классы фактически используются для каждого запроса ...

Разве это не накладные расходы, чтобы ВСЕГДА регистрировать все в контейнере?Возможно, мне не следует создавать экземпляр нового контейнера для каждого запроса (и использовать что-то вроде пула контейнеров)?

Каковы рекомендации для этого случая?

Большое спасибо.

Любые мысли приветствуются!

Ответы [ 2 ]

2 голосов
/ 04 ноября 2010

Во внутренней структуре у нас есть статический экземпляр контейнера Unity, который вешается на файл Global.asax и создается (и заполняется регистрациями) при запуске приложения.

При каждом запросе мы используем Container.CreateChildContainer () для получения контейнера, специфичного для запроса, который получает очень мало регистраций, специфичных для запроса (еще меньше, если вы используете Unity 2.0 с HierarchicalLifetimeManager).Контейнер для запроса - это то, что используется во время запроса.

Отредактировано, чтобы добавить: Не сказать, что это обязательно лучшая практика.Это, конечно, позволяет избежать каких-либо накладных расходов на регистрацию, за исключением запуска приложения, когда у меня есть более крупная рыба, которую нужно жарить с точки зрения издержек.

0 голосов
/ 05 ноября 2010

Я регистрирую все необходимое веб-приложением в Application_Start.У меня есть RequestLifetimeManager, как this и SessionLifeTimeManager, для создания зависимостей, специфичных для запроса и сеанса, которые должны создаваться только при необходимости: еще не видел проблем производительности или памяти, связанных с этим подходом,Наша политика заключается в создании дочернего контейнера, когда контекст отличается, например, в веб-службах или фоновых задачах.

...