2011-03-11 75 views
1

我一直在ASP.Net應用程序使用的數據層中使用Rick Strahl的DataContextFactory代碼(Linq to SQL DataContext Lifetime Management)。它工作得很好,因爲當前的datacontext存儲在HttpContext.Items集合中。我知道我正在重複使用每個Web請求的相同數據上下文。在使用DataContextFactory的WCF服務中管理Linq to SQL Datacontext

但是,我一直無法在WCF服務中成功使用工廠。在非HttpContext應用程序中,工廠將datacontext存儲在線程數據插槽中。

Thread.AllocateNamedDataSlot(key) 

的問題是,無論我怎麼設置我的服務ConcurrencyMode和InstanceContextMode,線程被重用每次調用和相同的DataContext被重用。我不想要這個。我只希望每個服務方法調用都存在單個數據上下文。有沒有什麼辦法可以使用工廠來實現?我無法在每個客戶端調用中找到任何唯一的信息作爲我的datacontext的標識符,因此不會被其他請求重用...無論它是否是同一個客戶端。

我想消費我的業務層,並且不直接訪問我的數據層,但恐怕我可能必須在我的WCF服務中指定自己的工作單元和數據上下文。有沒有人在WCF服務中使用某種工廠的datacontexts有任何運氣?我希望有辦法爲我廠知道,如果它是由一個WCF服務消費,然後處理DataContext的唯一

public static T GetScopedDataContext<T>() 
{ 
    if (HttpContext.Current != null) 
     return (T)GetWebRequestScopedDataContextInternal(typeof(T), typeof(T).ToString(), null); 

    // What can I put here to handle WCF services differently? 
    return (T)GetThreadScopedDataContextInternal(typeof(T), typeof(T).ToString(), null); 
} 

的存儲和再有什麼可以在這裏完成,以實現我想要什麼?

static object GetThreadScopedDataContextInternal(Type type, string key, string ConnectionString) 
{ 
    if (key == null) 
     key = "__WRSCDC_" + Thread.CurrentContext.ContextID.ToString(); 

    LocalDataStoreSlot threadData = Thread.GetNamedDataSlot(key); 

    object context = null; 

    if (threadData != null) 
     context = Thread.GetData(threadData); 

    if (context == null) 
    { 
     if (ConnectionString == null) 
      context = Activator.CreateInstance(type); 
     else 
      context = Activator.CreateInstance(type, ConnectionString); 

     if (context != null) 
     { 
      if (threadData == null) 
       threadData = Thread.AllocateNamedDataSlot(key); 

      Thread.SetData(threadData, context); 
     } 
    } 
    return context; 
} 

回答

0

我得到了同樣的問題。 我使用Castle.Windsor IOC容器+「PerWebRequest」生活方式,其工作方式與您的工廠相似。

我仍然試圖找到我需要的完美解決方案,但我有一箇中間的解決方案,可以幫助你:

1)在你的WCF項目:用HttpContext的讓您的WCF服務運行,要求ASP.Net兼容性

<system.serviceModel> 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> 
</system.serviceModel> 

2)對應的屬性添加到您的服務來管理這種兼容性

[AspNetCompatibilityRequirements(
    RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] 
public class MyService : IMyContract 
{ 
    ... 
} 

來源:Code rant