1

ASP.Net アプリケーションによって消費されるデータ層で、Rick Strahl の DataContextFactory コード ( Linq to SQL DataContext Lifetime Management ) を使用してきました。現在の datacontext が HttpContext.Items コレクションに格納されているため、うまく機能します。Web リクエストごとに同じデータ コンテキストを再利用していることはわかっています。

ただし、WCF サービスでファクトリを正常に使用できませんでした。非 HttpContext アプリでは、ファクトリは datacontext をスレッド データ スロットに格納します。

Thread.AllocateNamedDataSlot(key)

問題は、サービスで ConcurrencyMode と InstanceContextMode をどのように設定しても、呼び出しごとにスレッドが再利用され、同じ dataContext が再利用されることです。私はこれをしたくありません。サービスメソッド呼び出しごとに単一のデータコンテキストのみが存在するようにします。ファクトリを使用してこれを実現する方法はありますか? データコンテキストの識別子として使用する各クライアント呼び出しに関する一意の情報を見つけることができないため、同じクライアントであるかどうかに関係なく、他の要求で再利用されません。

ビジネス レイヤーを使用し、データ レイヤーに直接アクセスしたくないのですが、WCF サービスで独自の作業単位とデータ コンテキストを指定する必要があるのではないかと心配しています。WCF サービスのデータコンテキストにある種のファクトリを使用して運が良かった人はいますか? 工場がWCFサービスによって消費されているかどうかを知り、データコンテキストの保存を一意に処理する方法があることを望んでいました

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;
}
4

1 に答える 1

0

私は同じ問題を抱えています。私は Castle.Windsor IOC コンテナー + "PerWebRequest" ライフスタイルを使用しており、内部の工場と同様に機能します。

私はまだ自分のニーズに合った完璧な解決策を見つけようとしていますが、あなたを助けることができる中間的な解決策があります.HttpContextでWCFサービスを実行することです:

1) WCF プロジェクトで、ASP.Net 互換性を要求します。

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

2) サービスに属性を追加して、この互換性を管理します

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

出典:コード暴言

于 2011-04-29T14:19:06.837 に答える