1

WCF サービス (JSON 要求/応答を処理する) に Castle Windsor を使用しています。また、データ層で Entity Framework を使用しています。

LifeStyleを使用するPerWebRequestと、次のエラーがスローされます。

The server encountered an error processing the request. The exception message is 'HttpContext.Current is null. PerWebRequestLifestyle can only be used in ASP.Net'. See server logs for more details. The exception stack trace is:

at Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule.GetScope() at Castle.MicroKernel.Lifestyle.WebRequestScopeAccessor.GetScope(CreationContext context) at Castle.MicroKernel.Lifestyle.ScopedLifestyleManager.GetScope(CreationContext context) at Castle.MicroKernel.Lifestyle.ScopedLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy) at Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden) at Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired) at Castle.MicroKernel.Handlers.AbstractHandler.Resolve(CreationContext context) at Castle.MicroKernel.Resolvers.DefaultDependencyResolver.ResolveFromKernelByType(CreationContext context, ComponentModel model, DependencyModel dependency) at Castle.MicroKernel.Resolvers.DefaultDependencyResolver.ResolveFromKernel(CreationContext context, ComponentModel model, DependencyModel dependency) at Castle.MicroKernel.Resolvers.DefaultDependencyResolver.ResolveCore(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) at Castle.MicroKernel.Resolvers.DefaultDependencyResolver.Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateConstructorArguments(ConstructorCandidate constructor, CreationContext context) at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.Instantiate(CreationContext context) at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context) at Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context, Burden burden) at Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.CreateInstance(CreationContext context, Boolean trackedExternally) at Castle.MicroKernel.Lifestyle.SingletonLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy) at Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden) at Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired) at Castle.MicroKernel.Handlers.AbstractHandler.Resolve(CreationContext context) at Castle.MicroKernel.DefaultKernel.ResolveComponent(IHandler handler, Type service, IDictionary additionalArguments, IReleasePolicy policy) at Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(String key, Type service, IDictionary arguments, IReleasePolicy policy) at Castle.MicroKernel.DefaultKernel.Resolve[T](String key, IDictionary arguments) at Castle.Facilities.WcfIntegration.WindsorInstanceProvider.GetInstance(InstanceContext instanceContext, Message message) at System.ServiceModel.Dispatcher.InstanceBehavior.GetInstance(InstanceContext instanceContext, Message request) at System.ServiceModel.InstanceContext.GetServiceInstance(Message message) at System.ServiceModel.Dispatcher.InstanceBehavior.EnsureServiceInstance(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

LifeStyleを使用するPerWcfOperationと正常に動作しますが、データ レイヤーから同じデータが返されます (私の場合、データ レイヤーの各メソッドの前に _context を初期化しない限り、同じ UserStatus が返されます)。以下は、データ レイヤーでの GET メソッドの実装です。

PerWebRequest以下のメソッドは、 LifeStyleを使用するときに Web アプリケーションから期待される結果を提供します。

public class UserDAL: IUserDAL
{
    #region Declaration
    private MyDBContainer _context;
    #endregion

    #region Constructor
    public UserDAL()
    {
        _context = new MyDBContainer();
    }
    #endregion

    #region Get User Status
    /// <summary>
    /// Get User Status
    /// </summary>
    /// <param name="user"></param>
    /// <returns></returns>
    public User GetUserStatus(User user)
    {
        st_User _dbUser = null;
        if (user != null && user.UserId > 0)
        {
            _dbUser = _context.st_User.Where(u => u.User_Id == user.UserId && !u.Is_Deleted).SingleOrDefault();
        }
        if (_dbUser != null && _dbUser.User_Id > 0)
        {
            user.LastLoginDate = _dbUser.Last_Login_Date;
            user.UserStatus = (UserStatus)Enum.Parse(typeof(UserStatus), _dbUser.User_Status, true);
        }

        return user;
    }
    #endregion
}

LifeStyleを使用するPerWcfSessionと、次のエラーがスローされます。

The server encountered an error processing the request. The exception message is 'Could not obtain scope for component MyApp.DAL.UserDAL. This is most likely either a bug in custom IScopeAccessor or you're trying to access scoped component outside of the scope (like a per-web-request component outside of web request etc)'. See server logs for more details. The exception stack trace is:

at Castle.MicroKernel.Lifestyle.ScopedLifestyleManager.GetScope(CreationContext context) at Castle.MicroKernel.Lifestyle.ScopedLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy) at Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden) at Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired) at Castle.MicroKernel.Handlers.AbstractHandler.Resolve(CreationContext context) at Castle.MicroKernel.Resolvers.DefaultDependencyResolver.ResolveFromKernelByType(CreationContext context, ComponentModel model, DependencyModel dependency) at Castle.MicroKernel.Resolvers.DefaultDependencyResolver.ResolveFromKernel(CreationContext context, ComponentModel model, DependencyModel dependency) at Castle.MicroKernel.Resolvers.DefaultDependencyResolver.ResolveCore(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) at Castle.MicroKernel.Resolvers.DefaultDependencyResolver.Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateConstructorArguments(ConstructorCandidate constructor, CreationContext context) at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.Instantiate(CreationContext context) at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context) at Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context, Burden burden) at Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.CreateInstance(CreationContext context, Boolean trackedExternally) at Castle.MicroKernel.Lifestyle.SingletonLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy) at Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden) at Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired) at Castle.MicroKernel.Handlers.AbstractHandler.Resolve(CreationContext context) at Castle.MicroKernel.DefaultKernel.ResolveComponent(IHandler handler, Type service, IDictionary additionalArguments, IReleasePolicy policy) at Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(String key, Type service, IDictionary arguments, IReleasePolicy policy) at Castle.MicroKernel.DefaultKernel.Resolve[T](String key, IDictionary arguments) at Castle.Facilities.WcfIntegration.WindsorInstanceProvider.GetInstance(InstanceContext instanceContext, Message message) at System.ServiceModel.Dispatcher.InstanceBehavior.GetInstance(InstanceContext instanceContext, Message request) at System.ServiceModel.InstanceContext.GetServiceInstance(Message message) at System.ServiceModel.Dispatcher.InstanceBehavior.EnsureServiceInstance(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

以下は、Castle Windsor LifeStyle の使用方法です。

container.Register(Component.For<IUserDAL>().ImplementedBy<UserDAL>().LifeStyle.PerWcfSession());

PerWebRequestLifeStyleに相当する WCF に Castle Windsor を実装する最良の方法はどれですか? 提案してください

4

1 に答える 1

0

PerWcfOperation のライフスタイルは、まさにあなたが見つけたものです。オブジェクトは、操作全体を通じて存続します。これは、UserDAL が挿入されたビジネス サービスが、いくつかのデータベースの変更を行い、さらにいくつかのビジネス ロジックを実行してから、最終的に DbContext で commit を呼び出す前に、いくつかのビジネスの変更を行う必要がある作業単位の状況で特に価値があります。

MyDbContainer には、使用しているプラ​​イベート DbContext インスタンスがあるため、呼び出し全体で共有 DbContext が発生していると思います。

望ましくない動作を修正する方法は 2 つあります。まず、上記のコードには、これを wcf 操作の長さだけ持続させたい理由が見当たらないため、ライフスタイルを一時的にすることができます。

もう 1 つの解決策は、通常私がどのようにアプローチするかということですが、データにシングルトンにアクセスさせ、その場で適切なライフスタイル コンテキストをスピンアップする IContextFactory (私自身のインターフェイス) を挿入することです。

于 2013-10-26T00:49:54.393 に答える