2016-03-14 7 views
1

Я использую следующий код, где я получаю FXCop voilation CA2000: Утилизировать объект до потери сферы:«CA2000: Утилизировать объект до потери сферы» построение единства контейнера

private static IUnityContainer BuildContainer() 
{ 
    var container = new UnityContainer().LoadConfiguration(); 
    return container; 
} 

удалить это нарушение я использовал следующий код :

private static IUntyContainer BuildContainer() 
    { 
     using(var container = new UnityContainer()) 
     { 
      return container.LoadConfiguration(); 
     } 
    } 

Но этот код запускает исключение при разрешении зависимостей.

Может кто-нибудь помочь мне с этим?

+1

Я не понимаю ваш код. Эти два метода не возвращают одинаковое значение; второй возвращает значение, возвращаемое методом 'LoadConfiguration()', в то время как первый, как представляется, обрабатывает это значение как делегат (а?), вызывающий его и возвращающее возвращаемое значение. В более общем плане, хотя я не эксперт Unity, если объект, возвращаемый 'LoadConfiguration()', зависит от исходного объекта UnitContainer, вы не можете уничтожить этот оригинальный объект, пока не закончите с другим объектом. Вам нужно будет выяснить, что такое идиома Unity для обработки этого, а не просто слепо распоряжаться. –

+0

Попробуйте использовать метод 1: 'return container;' –

+0

Извините. Это было неправильно написано в первом фрагменте кода, который уже есть: 'return container', когда я пытаюсь удалить CA2000, создав' UnityContainer' внутри 'using', он утилизирует объект «UnityContainer» и исключить исключение ссылки на исключение в момент разрешения. Можете ли вы помочь мне с другим способом исправить это нарушение? –

ответ

2

Это нарушение, как правило, происходит из нескольких шаблонов коды, хотя вы должны смотреть на Help page for CA2000 для получения дополнительной информации

  • фабричных методами
  • Метод сцепления
  • Отсутствует или обработки неправильного исключения

Для чистых заводских методов, которые не имеют ничего другого, может быть в некоторых случаях достаточно, чтобы просто переименовать метод. Я не знаю, какие префиксы ищут правило, но вы можете попробовать Construct, Create, New, Build (тот, который у вас есть).

Это, однако, не то, что не так с этим методом в терминах CA2000.

Итак, давайте посмотрим на код в вопросе:

var container = new UnityContainer().LoadConfiguration(); 

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

Другими словами, метод выглядит примерно так:

public class UnityContainer 
{ 
    public UnityContainer LoadConfiguration() 
    { 
     // load 
     return this; 
    } 
} 

Анализ код двигателя теперь видит этот код:

var temp = new UnityContainer(); 
var container = temp.LoadConfiguration(); 
return container; 

Что случилось с temp? Он не может обнаружить (см. Мою заметку ниже), что это тот же самый экземпляр, поэтому он думает, что вы потеряли здесь экземпляр temp, и это должно быть удалено.

ОК, так как об изменении кода к этому:

var container = new UnityContainer(); 
container.LoadConfiguration(); 
return container; 

Теперь я получаю еще одно нарушение, из того же правила:

CA2000: В методе «Program.BuildContainer () ', объект «контейнер» не расположен по всем путям исключений. Вызовите System.IDisposable.Dispose на объекте 'container', прежде чем все ссылки на него выйдут из области видимости. ConsoleApplication31 C: \ Dev \ VS.NET \ ConsoleApplication31 \ ConsoleApplication31 \ Program.CS 18 Активный

В основном анализ код двигателя прямо сейчас задается вопросом, что произойдет, если LoadConfiguration бросает исключение, то вы бы просочиться временный объект-контейнер, который никогда не вернулся.

Так вот "фиксированная" версия этого метода:

var container = new Container(); 
try 
{ 
    container.LoadConfiguration(); 
    return container; 
} 
catch (Exception) // NOTE! 
{ 
    container.Dispose(); 
    throw; 
} 

ВНИМАНИЕ!: Используйте только те исключения, которые вы знаете, или думаете, что LoadConfiguration может бросать, не обрабатывать Exception.

Примечание: Когда я говорю «не обнаруживать» выше, это не означает, что у механизма анализа кода есть код для обнаружения этого, который либо терпит неудачу, либо имеет ошибку, это также может означать, что правило просто не делает этого глубокого анализа, например, глядя на метод LoadConfiguration и определяя, что он всегда возвращает this.

+0

его разрешено ... Спасибо за подробное объяснение ... :) –