2013-07-16 2 views
1

. Понятно, что я застрял в 2005 году и совсем недавно. Я знаю, что у меня много догоняют, но, поскольку мне не нравится неэффективный код, следующий фрагмент кода (внизу этого вопроса) из учебника SimpleInjector немного озадачен.Почему этот код DI объявляет метод-scope var, а затем назначает его статическому объекту уровня класса?

Проблема заключается в методе BootStrapper(), который используется для инициализации статического контейнера SimpleInjector.

В этом методе объявляется var container и назначается новый Container(). В конце метода область метода container затем назначается переменной статического уровня container уровня приложения.

Почему так делается? Должна быть веская причина для того, чтобы сначала назначить контейнер локальному var, а затем, наконец, присвоить переменную переменной static static Container. Для меня это кажется очевидным, избыточным заданием, но если это так, я сомневаюсь, что кто-то это сделает. Что мне не хватает?

Код, приведенный ниже, приведен из кода из документации SimpleInjector. Я понимаю все, что делает код, я просто не понимаю смысла этого дополнительного задания var.

using System.Windows; 
using SimpleInjector; 

public partial class App : Application 
{ 
    private static Container container; //<-- The static, class-level variable. 
             // Why not assign to it from the get-go?! 

    //...snip... 

    protected override void OnStartup(StartupEventArgs e) 
    { 
     base.OnStartup(e); 
     Bootstrap(); 
    } 

    private static void Bootstrap() 
    { 
     // Create the container as usual. 
     var container = new Container(); //What's the point of this var? 

     // Register your types, for instance: 
     container.RegisterSingle<IUserRepository, SqlUserRepository>(); 
     container.Register<IUserContext, WpfUserContext>(); 

     // Optionally verify the container. 
     container.Verify(); 

     // Store the container for use by the application. 
     App.container = container; //Couldn't we have done this from line 1 of this method? 
    } 
} 

Источник: SimpleInjector - Windows Presentation Foundation Integration Guide

ответ

7

Если контейнер присваивается статическое свойство сразу, то статическое свойство будет ссылаться на контейнер, который еще не полностью инициализирован, что может иметь нежелательные последствия.

Назначение контейнера статическому свойству только тогда, когда оно полностью инициализировано, не позволяет другим использовать частично инициализированный контейнер.

+0

См. Мой вопрос о должности Кевина. – RLH

+1

Многопоточность - одна из причин, но есть способы, которыми другие части кода могли получить доступ к частично инициализированному объекту. Зарегистрированные типы могут получить к нему доступ (например, WpfUserContext), и если будет создано исключение, метод Bootstrap может не завершить его выполнение, и, следовательно, частично инициализированный объект никогда не станет полностью инициализированным. – lightbricko

+0

Отличная (и несколько очевидная) точка! Да, мне нужно будет немного почитать об этом. Это мой первый проект Injection Dependency Injection, и я буду предоставлять услуги, которые должны будут ссылаться на службы. Я собираюсь обновить свои теги, потому что я начинаю видеть, как это относится к SimpleInjector и DI. – RLH

3

Я не знаю SimpleInjector, но возможной причиной может быть, если RegisterSingle, Register или Verify могут вызывать исключение. Если кто-то из них делает это, вы можете остаться с App.Container в недопустимом состоянии, тогда как делать это таким образом, App.Container будет оставлен либо в желаемом новом состоянии, либо останется нетронутым. При условии, что Контейнер является управляемым типом, вы получаете сильную исключительную безопасность (http://en.wikipedia.org/wiki/Exception_safety).

+0

У меня была эта мысль, но поскольку у метода не было обертки try/catch, похоже, для меня это не так много. В нынешних обстоятельствах исключение просто приведет к краху приложения. – RLH

+0

@RLH: Это зависит от типа приложения и того, когда в образе приложения используется код, если он отключает домен приложения. Если это не приведет к сбою приложения, каждый следующий запрос или операция даст странное сообщение об исключении, которое скрывает фактическую проблему. В прошлом я был немного этим (хотя это не приложение WPF). И хотя приложение WPF может умереть, когда «Application.OnStartUp» терпит неудачу, разработчики склонны копировать эти примеры кода, поэтому я думаю, что это не повредит, напишите некоторые примеры кода, которые немного более надежны :-) – Steven

+1

Основная причина исключений заключается в том, что вам не нужно обрабатывать их локально.Автор Bootstrap, возможно, не знает, что будет подходящим ответом на исключение, потому что он не знает, что такое конечное приложение. Предоставляя исключение, распространяющееся через дерево вызовов, автор передает ответ за отказ клиента, который в лучшем положении совершает вызов (или передает его по очереди своему клиенту и т. Д.). Не будучи завернутым в блок try, нет никаких указаний на то, что код не записывается с учетом безопасности исключений. – digitig

Смежные вопросы