我们将 Castle Windsor 用于 WCF 服务(处理 JSON 请求/响应)。我们也在数据层中使用实体框架。
当我们使用PerWebRequest
LifeStyle 时,它会抛出以下错误:
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)
当我们使用PerWcfOperation
LifeStyle 时,它工作正常,但它从数据层返回相同的数据(在我的情况下,它返回相同的 UserStatus,除非我在数据层中的每个方法之前初始化 _context)。下面是数据层中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
}
当我们使用PerWcfSession
LifeStyle 时,它会抛出以下错误:
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());
哪个是实现 Castle Windsor for WCF 相当于PerWebRequest
LifeStyle 的最佳方式?请建议