初始化服务时如何实现using语句?

How to implement a using statement when inititializing a service?

概览:

我在 XRM 项目中遇到了一些初始化代码,其中正在初始化的实例实现了 IDisposible,但实例上没有周围的 using 块。

在示例中,我 looked at 在 using 块中有一个在服务上调用的实例方法。但在我下面的例子中,服务实例刚刚被初始化。直到在私有方法的代码中进一步调用服务方法本身。

问题:

如何使用 using 块进行服务实例初始化?

代码示例 1:(服务初始化)

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:(我尝试实现 using 语句)

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?

    }

}

看来您对 using 语句有一些误解。如果从创建到处理服务的代码是本地范围的,则只能使用 using 语句。

你问题中的情况是,服务对象的生命周期超出了创建对象的范围。因此,您的选择是要么重新设计(为每次调用 GetUserInfo 创建一个新的服务对象),要么在没有 using 语句帮助的情况下管理服务生命周期。

MSDN Reference 中描述了 using 语句的等价物,即

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 实现 class 是可行的方法。但是,在您的情况下,您有静态方法和静态变量。所以第一个问题是,您期望使用寿命是多少?静态变量的默认答案是:"as long as the application is running" 然后很明显,为了确保正确清理,您必须做什么:

  • 如果 CreateSourceServiceObjects 被多次调用,要么确保在重新分配之前处理旧服务对象,要么拒绝重新初始化
  • 根据您的程序类型,挂接到应用程序出口并手动处理服务对象(如果已分配)

我想指出,通过将 class 重新设计为非静态,您可以在这里赢得很多。对于 class 的实例,您可以使用标准 IDisposable 模式,这可能比某些自定义程序退出清理代码更安全。

话虽如此,IF 您的服务正确实现了处置和终结功能,您根本不需要担心处置问题,因为您的静态对象会一直活到应用程序退出,然后通过终结器释放非托管资源。