我们正在开发基于
的Web应用程序为解析控制器,我们使用ControllerFactory类,如下页所述: http://docs.castleproject.org/Windsor.Windsor-tutorial-part-two-plugging-Windsor-in.ashx
为了解析依赖关系,我们使用WindsorDependencyResolver类:
public class WindsorDependencyResolver : IDependencyResolver
{
public IWindsorContainer Container { get; private set; }
public WindsorDependencyResolver(IWindsorContainer windsorContainer)
{
Container = windsorContainer;
}
public IDependencyScope BeginScope()
{
return new WindsorDependencyScope(this.Container);
}
public object GetService(Type serviceType)
{
return this.Container.Kernel.HasComponent(serviceType) ? this.Container.Resolve(serviceType) : null;
}
public IEnumerable<object> GetServices(Type serviceType)
{
return this.Container.ResolveAll(serviceType).Cast<object>().ToArray();
}
public void Dispose()
{
}
}
public class WindsorDependencyScope : IDependencyScope
{
public IWindsorContainer Container { get; set; }
public IDisposable Scope { get; set; }
public WindsorDependencyScope(IWindsorContainer container)
{
this.Container = container;
this.Scope = container.BeginScope();
}
public object GetService(Type serviceType)
{
return this.Container.Kernel.HasComponent(serviceType) ? this.Container.Resolve(serviceType) : null;
}
public IEnumerable<object> GetServices(Type serviceType)
{
return this.Container.ResolveAll(serviceType).Cast<object>().ToArray();
}
public void Dispose()
{
this.Scope.Dispose();
}
}
请记住,我们不会使用Windsor容器解析SignalR的IHub类,它们由管道中的OWIN系统实例化。 Startup.cs代码如下所示:
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
app.MapSignalR();
}
}
所有控制器,wcf服务客户端和拦截器(不包括日志记录类)都在项目中的LifestylePerWebRequest中注册。但是,我们用于记录的类是单例。
下面的Web.config中有一个设置:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
...
<add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
...
</modules>
</system.webServer>
因此,当我们尝试解决一个wcf客户端 - 它具有每个Web请求生活方式 - 在SignalR中心时,我们得到以下例外:
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'Scope cache was already disposed. This is most likely a bug in the calling code.'.
at Castle.MicroKernel.Lifestyle.Scoped.ScopeCache.get_Item(Object id)
at Castle.MicroKernel.Lifestyle.Scoped.DefaultLifetimeScope.GetCachedInstance(ComponentModel model, ScopedInstanceActivationCallback createInstance)
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.DefaultKernel.ResolveComponent(IHandler handler, Type service, IDictionary additionalArguments, IReleasePolicy policy)
at Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, IDictionary arguments, IReleasePolicy policy)
at Castle.MicroKernel.DefaultKernel.Resolve(Type service, IDictionary arguments)
at Castle.Windsor.WindsorContainer.Resolve[T]()
at UIServer.WebUI.Hubs.MailThreadHub.Broadcast(MailMessageListDto mailMessage) in c:\Development\DDD\UIServer.WebUI\Hubs\MailThreadHub.cs:line 92
在调用Container.Resolve()方法之前,我可以在调试器窗口中看到HttpContext。顺便说一下,我可以解决单例记录类。
有趣的是,我的队友没有任何例外。主要区别在于我们的OS版本。我在Windows 8.1中运行代码,我的队友在Windows 7中运行它。
我们仅针对信号器集线器获得此例外。我们在其他任何地方都没有例外。我们怎样才能解决这个问题?
答案 0 :(得分:0)
我在Startup类中使用ServiceLocator来解析IDependencyResolver。看起来像是:
internal class Startup
{
public void Configuration(IAppBuilder appBuilder)
{
var config = new HttpConfiguration();
config.Routes.MapHttpRoute("ActionApi", "{controller}/{action}/{id}", new {id = RouteParameter.Optional});
config.DependencyResolver = ServiceLocator.Instance.Resolve<IDependencyResolver>();
appBuilder.UseWebApi(config);
}
}
也许这是有帮助的。