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

标签 c# dynamics-crm idisposable using-statement xrm

概述:

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

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

问题:

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

代码示例 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 实现该类就是一种方法。但是,就您而言,您有静态方法和静态变量。所以第一个问题是,您期望的使用生命周期是多少?静态变量的默认答案是:“只要应用程序正在运行”,然后就清楚了,为了确保正确的清理,您必须做什么:

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

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

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

关于c# - 初始化服务时如何实现using语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35598359/

相关文章:

c# - 将空格附加到 stringbuilder 左对齐

c# - 如何在微服务分布式环境中创建一个简短易读的 UUID

dynamics-crm-2011 - 如何使用JavaScript将base64文件保存到客户端?

c# - 如何实例化对象并将其传递给 "using" block 声明中的方法

时间:2019-03-08 标签:c#interopmarshallinganddisposing

c# - 数值类型的 "base class"是什么?

c# - 绑定(bind)Command时绑定(bind)IsEnabled是可选的吗?

c# - 如何避免在类之间传递上下文引用

dynamics-crm - 部署 CRM 解决方案

c# - 在 Dispose 方法中取消任务