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

本文关键字:实现 using 语句 服务 初始化 | 更新日期: 2023-09-27 18:35:56

概述:

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

在我在 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语句有一些误解。仅当从创建到处置服务的代码是作用域本地的代码时,才能使用 using 语句。

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

MSDN 参考中描述了 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 实现类是方法。但是,在您的情况下,您有静态方法和静态变量。所以第一个问题是,你期望的使用寿命是多少?静态变量的默认答案是:"只要应用程序正在运行",然后就很清楚,为了确保正确清理,您必须做什么:

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

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

话虽如此,如果您的服务具有释放和最终功能的正确实现,则根本不需要担心释放,因为静态对象将一直存在到应用程序退出,然后通过终结器释放非托管资源。