2

プロジェクトで Unity.MVC3 を使用しています。

一般的な作業単位を実装UnitOfWork<TContext>しましたが、リクエストごとに作成したいと考えています。Unity.MVC3 を利用して、次のようにしました。

unityContainer.RegisterType(typeof(IUnitOfWork<>), typeof(UnitOfWork<>), new HierarchicalLifetimeManager());

ベースリポジトリ内で言及されたUOWを使用しています。ベース リポジトリは一部の特定のリポジトリで使用され、それらの特定のリポジトリは一部のサービスで使用されます。

UserRepository と UserService があるとします。

UserRepository コンストラクターは多かれ少なかれ次のようになります。

    public UserRepository(IUnitOfWork<UserContext> unitOfWork)
        : base(unitOfWork)
    {           
    }

UserService 内で UserRepository を使用していますが、UserRepository が使用するのと同じ UOW インスタンスが必要です。

public UserService(IUserRepository userRepository, IUnitOfWork<UserContext> unitOfWork)
{
}

Unity.MVC3 を使用し、HierarchicalLifetimeManager を使用して UOW を登録している間、UserRepository と UserService の両方で同じ UOW インスタンスを取得する必要があります。

問題は、初めて Web サイトを実行すると、2 つの異なる UOW インスタンスが作成され、この 2 つのインスタンスのうちの 1 つのみに対して Dispose メソッドが呼び出されることです。ページがロードされ、更新ボタンを押すと、すべてが正しいように見えます - 1 つのインスタンスのみが作成されます。

登録されたジェネリック型で問題が発生するようです。

問題を再現したい場合は、Unity.MVC3.Exampleコードをダウンロードし、IExampleContext をジェネリックにして実行してみてください。

問題の原因と、これを解決する方法について何か考えがありますか? 前もって感謝します。

4

2 に答える 2

0

実際、PerResolveLifetimeManagerが必要だと思います。

依存関係チェーンにUOWを1つだけ作成しますが、チェーンを解決するたびに新しいUOWが作成されます。

HierarchicalLifetimeManagerは反対の動作です。

于 2013-03-06T10:34:51.303 に答える
0

これが私の代替ソリューションです:

PerRequestLifetimeManager を作成しました:

public class PerRequestLifetimeManager<T> : LifetimeManager, IDisposable
{
    public override object GetValue()
    {
        return HttpContext.Current.Items[typeof(T).AssemblyQualifiedName];
    }
    public override void RemoveValue()
    {
        HttpContext.Current.Items.Remove(typeof(T).AssemblyQualifiedName);
    }
    public override void SetValue(object newValue)
    {
        HttpContext.Current.Items[typeof(T).AssemblyQualifiedName] = newValue;
    }
    public void Dispose()
    {
    }
}

UserDomain 内に IUnitOfWork タイプを登録しました。

RegisterType<IUnitOfWork<UsersContext>, UnitOfWork<UsersContext>>(new PerRequestLifetimeManager<IUnitOfWork<UsersContext>>());

PerRequestLifetimeHttpModule を作成し、Web.config に登録しました。

public class PerRequestLifetimeHttpModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.EndRequest += (sender, e) => UnityDependencyResolver.DisposePerRequestLifetimeItems();
    }
    public void Dispose()
    {
    }
}

<system.webServer>
    <modules runAllManagedModulesForAllRequests="false">
        <add name="PerRequestLifetimeHttpModule" type="<namespace>.PerRequestLifetimeHttpModule, <assemblyName>" />
    </modules>
</system.webServer

そして最後のステップ - カスタム UnityDependencyResolver 内で、PerRequestLifetimeHttpModule で使用される DisposePerRequestLifetimeItems 静的関数を作成しました。

public static void DisposePerRequestLifetimeItems()
{
    foreach (var item in HttpContext.Current.Items.OfType<DictionaryEntry>().Where(item => item.Value is IDisposable))
    {
        ((IDisposable)item.Value).Dispose();
    }
}
于 2013-03-13T18:42:43.913 に答える