0

私は本当にここで立ち往生しています。

asp.net mvcアプリケーションがあり、StructureMap 2.5.3(SM)を使用してコントローラーにサービスクラスとリポジトリクラスを挿入しています。すべてのコントローラーはSM工場で製造されています。

ハイブリッドでキャッシュしたいLinqtoSQLデータコンテキストもあります。

public class DBRegistry:Registry
{
    public  DBRegistry()
    {
        ForRequestedType<SharpShopDataContext>()
            .CacheBy(StructureMap.Attributes.InstanceScope.Hybrid)
            .TheDefault.IsThis(new SharpShopDataContext());
    }
}

キャッシングが機能していないようで、そのためにデータコンテキストに問題が発生します。

複数のブラウザリクエストはすべて同じdbcontextを返しますか?!私のリポジトリクラスの1つに、このコードを配置しました。Debug.WriteLine( "db hashcode:" + db.GetHashCode()+ "" + DateTime.Now.ToString());

ここで、db = the datacontextまた、dbを使用してリポジトリのハッシュコードを出力し、リポジトリを使用してサービスを出力します。これは、複数のリクエストの出力です。

サービスハッシュコード:6238792 26-3-2009 18:59:34

リポジトリハッシュコード:21756593 26-3-2009 18:59:34

dbハッシュコード:7043935 26-3-2009 18:59:34

サービスハッシュコード:59389065 26-3-2009 18:59:34

リポジトリハッシュコード:8331620 26-3-2009 18:59:34

dbハッシュコード:7043935 26-3-2009 18:59:34

サービスハッシュコード:11291358 26-3-2009 18:59:38

リポジトリハッシュコード:13848497 26-3-2009 18:59:38

dbハッシュコード:7043935 26-3-2009 18:59:38

サービスハッシュコード:42509361 26-3-2009 18:59:38

リポジトリハッシュコード:56101068 26-3-2009 18:59:38

dbハッシュコード:7043935 26-3-2009 18:59:38

ご覧のとおり、7043935はリクエストごとに毎回データコンテキストのハッシュコードですが、サービスとリポジトリは毎回新しいインスタンスとハッシュコードを取得します。

これが原因で奇妙なエラーが発生します。たとえば、データベースが別のソースによって変更されているときに、dbcontextが4つのwebrequests前の元の値を持っているためにデータ同時実行例外が発生します。

4

3 に答える 3

3

DataContextSM にHttpRequest ごとに 1 つ作成させようとしている場合は、新しいRegistry構成が機能するはずです。

ForRequestedType<ISharpShopDataContextWrapper>()
            .CacheBy(StructureMap.Attributes.InstanceScope.Hybrid)
            .TheDefaultIsConcreteType<SharpShopDataContextWrapper>();

InstanceScope.Hybrid「スレッドまたはASP.NETリクエストごとに1回」のライフサイクルが必要な場合に使用する必要があるSM(v2.5.3)列挙値です(ソースのChad Myers、SM contributorに行きましょう)

アプリケーション インフラストラクチャを適切に構成すれば、「多くのコードを変更する必要はありません」。のラッパークラスを作成することにした理由を知りたいSharpShopDataContextですか? LinqToSqlは部分クラスとして宣言されているため、追加のインターフェイスを実装DataContextする部分クラスを簡単に作成できます。SharpShopDataContext

LinqToSql で生成された部分クラス定義

public partial class SharpShopDataContext: System.Data.Linq.DataContext{
    /*Linq2Sql gen here*/
}

部分クラス定義

public partial class SharpShopDataContext: ISharpShopDataContext{
   /*your implementation here*/
}

Jeremy Miller の StructureMap の記事を読むことを検討してください。その機能をよく理解したら、おそらく MVC アプリケーション全体をリファクタリングするでしょう。現在のベース MVC アプリ フレームワークは、SM IoC (および試行錯誤/匂い/リファクタリングの負荷) により、高度に構成/テスト可能であることを知っています。

于 2009-07-18T04:57:57.170 に答える
2

これは間違いなく問題の行です。

.TheDefault.IsThis

特定のインスタンスを指定しているため、PerRequestを指定しても同じインスタンスが返されます。(回避策で)次のように変更したことに注意してください。

.TheDefaultIsConcreteType<SharpShopDataContextWrapper>();

追伸 私はHybridScopeを使用していませんが、デフォルトのインスタンススコープ(PerRequest)を使用する本番アプリがあり、データコンテキストを渡すたびに新しいインスタンススコープを確実に提供します。インスタンス化の方法を具体的に制御する場合は、式を受け入れる方法の1つを試して、次のように送信します。

() => new MyDataContext()
于 2009-03-26T21:04:16.707 に答える
0

回避策はありますが、多くのコードを変更する必要があることを知っているため、満足していません。試行錯誤の末に発見しました。

私は今使用しています:

            ForRequestedType<ISharpShopDataContextWrapper>()
            .CacheBy(StructureMap.Attributes.InstanceScope.Hybrid)
            .TheDefaultIsConcreteType<SharpShopDataContextWrapper>();

インターフェイスの注入/キャッシュは機能しているようです。これは、インターフェイス + 具体的なラッパーの実装です。

それは本当にSMのバグのように見えますか、それとも何か足りないのでしょうか?

public interface ISharpShopDataContextWrapper
{
    SharpShopDataContext DataContext
    {
        get;
    }
}

public class SharpShopDataContextWrapper : ISharpShopDataContextWrapper
{
    SharpShopDataContext db;

    public SharpShopDataContextWrapper()
    {
        db = new SharpShopDataContext();
    }
    public SharpShopDataContext DataContext
    {
        get { return db; }
    }
}
于 2009-03-26T20:29:47.790 に答える