2009-03-26 19 views
0

私は本当にここで立ち往生しています。構造マップInstanceScope.Hybrid asp.net mvc misbehaves

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

私はハイブリッドでキャッシュしたいLinq to SQLのdatacontextも持っています。

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

キャッシングが機能していないように見え、そのためにdatacontextに問題が発生します。

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

DBは=私はここでも、リポジトリを使用してDBおよびサービスを使用してリポジトリのハッシュコードを印刷するのDataContext は、複数の要求の印刷である:

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

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

デシベルのハッシュコード:7043935 26-3-2009 18時59分34秒

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

リポジトリハッシュコード:8331620 26-3-2009午後6時59分34秒

デシベルのハッシュコード:7043935 26-3-2009午後6時59分34秒

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

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

デシベルのハッシュコード:7043935 26-3-2009 18時59分38秒

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

リポジトリのハッシュコード:56101068 26-3-2009午後06時59分38秒

デシベルのハッシュコード:7043935 26-3-2009午後06時59分38秒

あなたは7043935でのハッシュコードで見ることができるようにdatacontextを各リクエストごとに毎回実行しますが、サービスとリポジトリは毎回新しいインスタンスとハッシュコードを取得します。

データベースコンシューマの例外のような奇妙なエラーが発生するのは、データベースが別のソースによって変更されていた間に、dbcontextが前回の4つのwebrequestsの元の値を持つためです。

+0

InstanceScopeをPerRequestに変更すると、同じ結果が得られます。すべてのdbハッシュコードは同じです。手動で2つの別々のdbcontextを作成すると、2つの異なるハッシュコードが与えられます。 – user81129

答えて

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

これは間違いなく問題のラインです:

.TheDefault.IsThis 

あなたが特定のインスタンスを指定している、これはPerRequestを指定しても同じことを返すために引き起こすものです。 (あなたの回避策で)に変更したことに気づいた:

.TheDefaultIsConcreteType<SharpShopDataContextWrapper>(); 

Ps。私はHybridScopeを使用していませんが、私はデフォルトのインスタンススコープ(PerRequest)を使用するプロダクションアプリを持っており、datacontextを渡すたびに新しいアプリケーションスコープを提供します。あなたはそれがインスタンス化され、具体的方法を制御したい場合は、式を受け入れるのいずれかの方法を試してみてください、あなたが送っその方法:

() => new MyDataContext() 
3

あなたはSMがあなたの新しいよりのHttpRequestごとに単一のDataContextを作成するために取得しようとしている場合Registry構成は

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

InstanceScope.Hybridがしたい場合は、「スレッドまたはASP.NETリクエストごとに一度」のライフサイクルは、(ソースChad Myers、SMに行くことができますあなたが使用する必要があるSM(V2.5.3)列挙型の値であり、動作するはずですcontributor

アプリケーションインフラストラクチャを適切に構成する場合、「多くのコードを変更する必要はありません」。 SharpShopDataContextのラッパークラスを作成することに決めた理由は興味深いでしょうか?が生成

LinqToSqlパーシャルクラス定義

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

あなたパーシャルクラス定義

:あなたは簡単に任意の追加のインタフェースを実装しSharpShopDataContext部分クラスを作成することができるようにLinqToSql DataContextは、部分クラスとして宣言されています
public partial class SharpShopDataContext: ISharpShopDataContext{ 
    /*your implementation here*/ 
} 

Jeremy Miller's StructureMap articlesの一部を読むことを検討してください。その機能をよく理解すれば、おそらくMVCアプリケーション全体をリファクタリングします。私は私の現在の基本MVCアプリケーションフレームワークは、SM IoC(および試行錯誤/匂い/リファクタのボートロード)のために設定可能/テスト可能であることを知っています。

関連する問題