如何提取使用 "using" 关键字且一次性的方法

How to extract a method which is using "using" keyword and is disposable

我有大约 20 个方法,其中大部分需要 UserPrincipalExtension 一次性 class 来做一些不同的操作,我想将它提取到一个单独的方法中,但我不确定如何,

public static UserPrincipalExtension GetUPE(Identity type, string identity)
    {
        using (PrincipalContext pc = MyUtilities.GetPrincipalContext())
        using (UserPrincipalExtension UPE = UserPrincipalExtension.FindByIdentity(pc, type, identity))
        {
             // do different operations
            // if I return UPE here then would pc going to dispose itself ?
        }

     // how best to return UPE and dipose pc as well, return UPE;
    }

所以我可以像这样在其他方法中使用它:

var UPE = GetUPE(IdentityType.SID, "S-32sldkfjsldr344");
using(UPE)
{

}

UPEPrincipalContext 应该放在后面。

除非 UPE 有自己的方式来处理主体上下文,否则您基本上有两个选择 - 在 UPE 周围创建一个包装器 class,或者使用辅助函数。

关于包装器 class 方法没什么可说的 - 只需有一个 class,它有一个用于 PC 和 UPE 的字段,并让它的 Dispose 方法处理两者的。根据您的要求,制作 UPE public,或公开您需要的方法。最简单的示例可能是这样的:

class UpeWrapper : IDisposable
{
  public readonly PrincipalContext PrincipalContext;
  public readonly UserPrincipalExtension UserPrincipalExtension;

  public UpeWrapper(PrincipalContext principalContext, 
                    UserPrincipalExtension userPrincipalExtension)
  {
    this.PrincipalContext = principalContext;
    this.UserPrincipalExtension = userPrincipalExtension;
  }

  public void Dispose()
  {
    try
    {
      UserPrincipalExtension.Dispose();
    }
    finally
    {
      PrincipalContext.Dispose();
    }
  }
}

使用辅助函数稍微少一点样板:

void UseUserPrincipalExtension(Identity type, string identity, 
                               Action<UserPrincipalExtension> action)
{
  using (PrincipalContext pc = MyUtilities.GetPrincipalContext())
  using (UserPrincipalExtension UPE = 
         UserPrincipalExtension.FindByIdentity(pc, type, identity))
  {
    action(UPE);
  }
}

而且用法也很简单:

UseUserPrincipalExtension
  (
    a, b, 
    upe => 
    {
      // Do your work here
    }
  );

我认为一种可能的方法是这样,但我不完全确定它是否会确定处理 principalContext 并且仍然让我使用继承自 System.DirectoryServices.AccountManagement.UserPrincipal[=13= 的 UserPrincipalExtension class ]

public static UserPrincipalExtension GetUPE(Identity type, string identity)
{
     UserPrincipalExtension UPE = null;
     using (PrincipalContext pc = MyUtilities.GetPrincipalContext())
     {
        UPE = UserPrincipalExtension.FindByIdentity(pc, type, identity));
     }
     return UPE;
}

上面的方法,pc会被销毁,然后其他的方法,

var UPE = GetUPE(IdentityType.SID, "S-32sldkfjsldr344");
using(UPE)
{

}