AutofacLifetimeScopeDecorator只希望对请求/响应管道的生命周期采取行动。我在下面有一个演示实例:publicclassProgram{publicstaticvoidMain(){varbuilder=newContainerBuilder();builder.RegisterAssemblyModules(typeof(HandlerModule).Assembly);builder.RegisterType().AsSelf().InstancePerMatchingLifetimeScope("管道");varcontainer=builder.Build();使用(varscope=container.BeginLifetimeScope(“pipline”)){varpingHandler=scope.Resolve();pingHandler.Handle(新的PingRequest());”))).Select(interfaceType=>newKeyedService("IHandle",interfaceType)));builder.RegisterGenericDecorator(typeof(SecondDecoratorHandler),typeof(IHandle),"IHandle").Keyed("SecondDecoratorHandler",typeof(IHandle));builder.RegisterGenericDecorator(typeof(FirstDecoratorHandler),typeof(IHandle),"SecondDecoratorHandler");}}publicclassLifetimeScopeTester{}publicinterfaceIHandle其中TRequest:class,IRequest{TResponseHandle(TRequestrequest);}publicinterfaceIRequest{}publicclassPingRequest:IRequest{}publicclassPingResponse{}publicclassPingHandler:IHandle{publicPingResponseHandle(PingRequestrequest){Console.WriteLine("PingHandler");返回新的PingResponse();}}publicclassFirstDecoratorHandler:IHandlewhereTRequest:class,IRequest{privatereadonlyIHandle_decoratedHandler;私人只读LifetimeScopeTester_lifetimeScopeTester;publicFirstDecoratorHandler(IHandledecoratedHandler,LifetimeScopeTesterlifetimeScopeTester){_decoratedHandler=decoratedHandler;_lifetimeScopeTester=lifetimeScopeTester;}publicTResponseHandle(TRequestrequest){Console.WriteLine("FirstDecoratorHandler-LifetimeScopeTester[{0}]",_lifetimeScopeTester.GetHashCode());返回_decoratedHandler.Handle(请求);}}publicclassSecondDecoratorHandler:IHandlewhereTRequest:class,IRequest{privatereadonlyIHandle_decoratedHandler;私人只读LifetimeScopeTester_lifetimeScopeTester;publicSecondDecoratorHandler(IHandledecoratedHandler,LifetimeScopeTesterlifetimeScopeTester){_decoratedHandler=decoratedHandler;_lifetimeScopeTester=lifetimeScopeTester;}publicTResponseHandle(TRequestrequest){Console.WriteLine("SecondDecoratorHandler-LifetimeScopeTester[{0}]",_lifetimeScopeTester.GetHashCode());返回_decoratedHandler.Handle(请求);是的,我将pipleine包装在一个名为pipeline的范围内,这意味着每当我解析LifetimeScopeTester(管道范围)时,我都会得到相同的实例我想我可以替换using(varscope=container.BeginLifetimeScope("pipline")){varpingHandler=scope.Resolve();pingHandler.Handle(新的PingRequest());}与varpingHandler=scope.Resolve();pingHandler.Handle(新的PingRequest());通过创建另一个做同样事情的装饰器。我的第一个直觉是:私有只读IHandle_decoratedHandler;publicLifetimeScopeDecoratorHandlerAttempt1(ILifetimeScopescope,IHandledecoratedHandler){_scope=scope;_decoratedHandler=decoratedHandler;}publicTResponseHandle(TRequestrequest){Console.WriteLine("LifetimeScopeDecoratorHandler");TResponse响应;使用(_scope.BeginLifetimeScope("pipeline")){response=_decoratedHandler.Handle(request);}返回响应;当decoratedHandler句柄已经被resolved时,它不会被resolved。所以我试过:publicclassLifetimeScopeHandler:IHandlewhereTRequest:class,IRequest{privatereadonlyILifetimeScope_scope;私有只读Func_decoratedHandlerFactory;publicLifetimeScopeHandler(ILifetimeScopescope,FuncdecoratedHandlerFactory){_scope=scope;_decoratedHandlerFactory=decoratedHandlerFactory;}publicTResponseHandle(TRequestrequest){Console.WriteLine("LifetimeScopeDecoratorHandler");TResponse响应;使用(_scope.BeginLifetimeScope("pipeline")){vardecoratedHandler=_decoratedHandlerFactory();response=decoratedHandler.Handle;request)}returnresponse;但是,当调用_decoratedHandlerFactory()以尝试再次使用LifetimeScopeHandler装饰器包装内部处理程序时,这会无限重复。这就是我想要实现的目标。我在https://dotnetfiddle.net/hwujNI创建了一个dotnetfiddle来演示这个问题。当LifetimeScopeHandler类的Handle方法调用decoratedHandlerFactory委托时,它要求Autofac解析IHandle,这是一个LifetimeScopeHandler。这就是你有StackOverflowException的原因。我们可以将您的情况简化为以下代码示例:publicclassFoo{publicFoo(FuncfooFactory){this._fooFactory=fooFactory;}私有只读Func_fooFactory;publicvoidDo(){Foof=this._fooFactory();f.Do();即使有一个Foo实例,你也会得到一个StackOverflowException。要解决此问题,您必须向Autofac指示LifetimeScopeHandler的decoratedHandlerFactory委托不应是LifetimeScopeHandler的委托。您可以使用WithParameter来指示具有特定参数的最后一个装饰器:builder.RegisterGenericDecorator(typeof(LifetimeScopeHandler),typeof(IHandle),"FirstDecoratorHandler").WithParameter((pi,c)=>pi.Name=="decoratedHandlerFactory",(pi,c)=>c.ResolveKeyed("FirstDecoratorHandler",pi.ParameterType)).As(typeof(IHandle));使用此配置,输出将是LifetimeScopeHandlerFirstDecoratorHandler–LifetimeScopeTester[52243212]SecondDecoratorHandler–LifetimeScopeTester[52243212]PingHandler顺便说一句,您希望LifetimeScopeHandler成为一个特殊的装饰器,它将在特殊范围内创建内部IHandler。您可以通过要求LifetimeScopeHandler为您创建正确的作用域并解析先前的Ihandler来完成此操作。publicclassLifetimeScopeHandler:IHandlewhereTRequest:class,IRequest{privatereadonlyILifetimeScope_scope;publicLifetimeScopeHandler(ILifetimeScopescope){this._scope=scope;}publicTResponseHandle(TRequestrequest){控制台。WriteDecorLine("LifetimeScope"ILifetimeScopes=this._scope.BeginLifetimeScope("pipline")){vardecoratedHandler=s.ResolveKeyed("FirstDecoratorHandler");TResponseresponse=decoratedHandler.Handle(request);返回响应;这个实现将需要LifetimeScopeHandler知道链上的第一个装饰器,我们可以通过在其构造函数上发送名称来绕过它。publicclassLifetimeScopeHandler:IHandlewhereTRequest:class,IRequest{privatereadonlyILifetimeScope_scope;私有只读字符串_previousHandlerName;publicLifetimeScopeHandler(ILifetimeScopescope,StringpreviousHandlerName){this._scope=scope;this._previousHandlerName=previousHandlerName;}publicTResponseHandle(TRequestrequest){Console.WriteLine("LifetimeScopeDecoratorHandler");使用(ILifetimeScopes=this._scope.BeginLifetimeScope("pipline")){vardecoratedHandler=s.ResolveKeyed(previousHandlerName);TResponseresponse=decoratedHandler.Handle(request);返回响应;}}}你必须像这样登记:我们也可以通过不使用RegisterGenericDecorator方法绕过一次。如果我们像这样注册LifetimeScopeHandler:);ILifetimeScopepipelineScope=scope.BeginLifetimeScope("pipline");varo=piplineScope.ResolveKeyed("FirstDecoratorHandler",pi.ParameterType);scope.Disposer.AddInstanceForDisposal(piplineScope);返回o;}).As(typeof(IHandle));LifetimeScopeHandler现在看起来像所有的装饰器:publicLifetimeScopeHandler(IHandledecoratedHandler){this._decoratedHandler=decoratedqueHandler;}publicTResponseResponse){Console.WriteLine("LifetimeScopeDecoratorHandler");TResponseresponse=this._decoratedHandler.Handle(request);返回响应;顺便说一句,如果你在范围内使用多个IHandler,并且你需要一个管道范围,那么这个解决方案可能会有问题。要解决此问题,您可以查看此dotnetfiddle:https://dotnetfiddle.net/rQgy2X但在我看来它很复杂,您可能不需要它。以上就是C#学习教程:AutofacLifetimeScopeDecorator分享的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处: