背景は、リポジトリとUnitOfWorkパターンを備えたEntityFrameworkを使用するASP.NETWebFormsアプリケーションです。アプリケーションは、セッションmgtにout-of-proc StateServerを使用するようにも構成されていることに注意してください。これは、セッションに格納するものはすべてシリアル化可能でなければならないことを意味します。
また、各HttpRequestでUnitOfWorkオブジェクト(エンティティコンテキストオブジェクトを含む)を作成し、それをHttpContext.Current.Itemsに格納し、もちろん各リクエストの最後に破棄するようにHttpModuleを構成しています。
UnitOfWorkクラス自体には、各リポジトリのプロパティとエンティティコンテキスト自体が含まれています。
将来、より柔軟なテストを可能にするために、エンティティコンテキストのメソッドとプロパティのシグネチャを使用してIObjectContextインターフェイスを作成し、エンティティコンテキストの部分クラスを作成して継承しました。
public class UnitOfWork : IUnitOfWork
{
private IObjectContext context;
}
public UnitOfWork(IObjectContext context)
{
this.context = context;
}
public partial class MyEntities : IObjectContext
{
}
private static void ApplicationBeginRequest(Object source, EventArgs e)
{
if (!HttpContext.Current.Items.Contains("UnitOfWork"))
{
IUnitOfWork unitOfWork = new UnitOfWork();
HttpContext.Current.Items.Add("UnitOfWork", unitOfWork);
}
}
private void ApplicationEndRequest(object sender, EventArgs e)
{
if (HttpContext.Current.Items["UnitOfWork"] != null)
((IUnitOfWork)HttpContext.Current.Items["UnitOfWork"]).Dispose();
}
ここでの目標は、最終的には、エンティティコンテキストオブジェクトを偽造して、たとえばテスト目的でメモリ内コンテキストを作成できるようにすることです。
エンティティコンテキストオブジェクトで「シリアル化可能としてマークされていない」例外が発生し始めるまで、すべてが順調に進んでいました。明らかに、私の最初の考えは、部分エンティティコンテキストクラスに[Serializable]を追加することでしたが、その後、アセンブリSystem.Data.EntityのSystem.Data.Objects.ObjectContextがシリアル化可能としてマークされていないと文句を言い始めました(これは明らかにしません)制御できます)。
ここで何が欠けていますか?エンティティコンテキストオブジェクトをHttpContext.Current.Itemsに格納できないようです。これは、作業単位パターンの実装で実行する必要があります。
これは、インプロセスセッションmgtの代わりにASP.NET State Serverを使用しているためですか?確かに、State Serverを使用している場合、HTTPリクエストの存続期間中コンテキストを保存する方法はありますか?
ここで明らかな何かが欠けているような気がします。UnitOfWorkからMyEntitiesコンテキスト、各リポジトリクラスまで、すべてに[Serializable]を追加しました。それでも、エンティティコンテキスト自体を通過することはできません。
何か案は?
更新(スタックトレースの追加):
[SerializationException: Type 'myDAL.Model.myEntities' in Assembly 'myDAL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.]
System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type) +14324629
System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context) +408
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() +420
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder) +532
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo) +969
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) +633
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck) +322
System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer) +1487
[HttpException (0x80004005): Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode.]
System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer) +2485899
System.Web.SessionState.SessionStateItemCollection.WriteValueToStreamWithAssert(Object value, BinaryWriter writer) +49
System.Web.SessionState.SessionStateItemCollection.Serialize(BinaryWriter writer) +746
System.Web.SessionState.SessionStateUtility.Serialize(SessionStateStoreData item, Stream stream) +336
System.Web.SessionState.SessionStateUtility.SerializeStoreData(SessionStateStoreData item, Int32 initialStreamSize, Byte[]& buf, Int32& length, Boolean compressionEnabled) +99
System.Web.SessionState.OutOfProcSessionStateStore.SetAndReleaseItemExclusive(HttpContext context, String id, SessionStateStoreData item, Object lockId, Boolean newItem) +3828904
System.Web.SessionState.SessionStateModule.OnReleaseState(Object source, EventArgs eventArgs) +1021
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +80
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +165