2016-02-24 2 views
1

Обзор:Как реализовать оператор using при инициализации службы?

Я наткнулся на какой-то код инициализации в XRM проекте, где экземпляры инициализируемого реализации IDisposible но не окружающих, используя блок на экземплярах.

В примерах у меня есть looked at внутри используемого блока есть метод экземпляра, вызываемый службой. Но в моем случае ниже экземпляр службы просто инициализирован. Сами методы обслуживания не вызываются до тех пор, пока они не будут включены в код в частных методах.

Вопрос:

Как использовать используя блок для инициализации экземпляра службы?

Пример кода 1: (Service Init)

public static void Init(string connectionString, string name) 
{ 
    instanceName = name; 
    CreateSourceServiceObjects(connectionString); 
} 

//Service instances just Init here no methods are called: 
private static void CreateSourceServiceObjects(string connectionString) 
{ 
    var connection = CrmConnection.Parse(connectionString);   
    sourceService = new OrganizationService(connection); 
    sourceContext = new OrganizationServiceContext(sourceService); 
} 

//Example of where the sourceService method's are used: 
public static Entity GetUserInfo(Guid userId) 
{ 
    Entity systemuser = sourceService.Retrieve("systemuser", userId, new ColumnSet(true)); 
     return systemuser; 
} 

Пример кода 2: (Моя попытка реализации с помощью заявления)

private static void CreateSourceServiceObjects(string connectionString) 
{ 
    var connection = CrmConnection.Parse(connectionString); 

    //Added a Using block to auto dispose OrganizationService and OrganizationServiceContext 
    using(sourceService = new OrganizationService(connection)) 
    using (sourceContext = new OrganizationServiceContext(sourceService)) 
    { 
     //should there be any code in here? 

    } 

} 

ответ

2

Похоже, у вас есть неправильное представление о заявлении using. Оператор using может использоваться только в том случае, если код от создания до распоряжения этой службой является локально локальным.

Ситуация в вашем вопросе заключается в том, что время жизни объекта службы превышает область действия, в которой создается объект. Таким образом, ваши варианты, чтобы изменить дизайн (создать новый объект службы для каждого вызова до GetUserInfo) или управлять временем жизни службы без помощи оператора using.

Эквивалент с использованием заявления описано в MSDN Reference и говорит, что

using (Font font1 = new Font("Arial", 10.0f)) 
{ 
    byte charset = font1.GdiCharSet; 
} 

является краткой формой для

{ 
    Font font1 = new Font("Arial", 10.0f); 
    try 
    { 
     byte charset = font1.GdiCharSet; 
    } 
    finally 
    { 
     if (font1 != null) 
      ((IDisposable)font1).Dispose(); 
    } 
} 

Обычно, реализуя класс с IDisposable будет путь. Однако в вашем случае у вас есть статические методы и статические переменные. Итак, первый вопрос: что вы ожидаете от службы? Ответ по умолчанию для статических переменных будет: «до тех пор, как приложение работает», а затем становится ясно, что вы должны сделать для того, чтобы обеспечить надлежащую очистку:

  • Если CreateSourceServiceObjects вызывается более чем один раз, eigher обеспечить утилизацию старого объекта сервиса, прежде чем переназначение или отклонить повторную инициализацию
  • в зависимости от типа программы, внедриться в выход из приложения и вручную расположить объект службы, если он назначен

Я хочу укажите, что вы можете выиграть много здесь, изменив свой класс на нестатический. С экземпляром вашего класса вы можете просто пойти со стандартным шаблоном IDisposable, который, вероятно, безопаснее, чем какой-то код очистки пользовательского программного кода.

Сказав все это, ЕСЛИ ваша служба имеет надлежащую реализацию распоряжается и завершить функциональность, вам не нужно беспокоиться о распоряжении на всех, так как ваш статический объект будет просто дожить до выхода из приложения, а затем бесплатно неуправляемые ресурсы через финализатор.

+0

Хорошо, тогда это имеет смысл. –