【问题标题】:Injecting dependencies into an IErrorHandler while hosting in IIS在 IIS 中托管时将依赖项注入 IErrorHandler
【发布时间】:2016-03-03 19:38:58
【问题描述】:

我刚刚阅读了this 很好的答案,如何将依赖项注入 WCF 服务。解决方案非常简洁,但我有一个问题。

此答案中的解决方案使用自托管(控制台应用程序),因此可以实现自己的 ServiceHostErrorHandler 并执行以下操作:

var logger = new DummyLogger();
var errorHandler = new TestErrorHandler(logger);

ServiceHost host = new TestServiceHost(errorHandler, typeof(TestService), new Uri("net.tcp://localhost:8002"));
 host.Open();

我的问题是,如何在 ASP.NET Web 应用程序宿主中做到这一点?我试图在通过 IIS 托管时向服务中注入一些东西。任何帮助都会很棒!

【问题讨论】:

    标签: c# .net wcf iis ierrorhandler


    【解决方案1】:

    温莎城堡的WCF Integration Facility 就是这样做的。

    nuget 包添加到您的WCF 项目中。 在您的应用程序启动中(global.asax 或您创建的一些引导类):

    using System;
    using Castle.Facilities.WcfIntegration;
    using Castle.Windsor;
    using Castle.Windsor.Installer;
    
    namespace WcfService1
    {
        public class Global : System.Web.HttpApplication
        {
            static readonly IWindsorContainer Container = new WindsorContainer();
            protected void Application_Start(object sender, EventArgs e)
            {
                ConfigureContainer();
            }
    
            private void ConfigureContainer()
            {
                Container.AddFacility<WcfFacility>();
                Container.Install(FromAssembly.This());
            }
        }
    }
    

    然后添加一个安装程序类。 Container.Install(FromAssembly.This()) 将执行您服务中的任何安装程序。

    using Castle.Core.Logging;
    using Castle.MicroKernel.Registration;
    using Castle.MicroKernel.SubSystems.Configuration;
    using Castle.Windsor;
    
    namespace WcfService1
    {
        public class WindsorInstaller : IWindsorInstaller
        {
            public void Install(IWindsorContainer container, IConfigurationStore store)
            {
                container.Register(
                    Component.For<IYourService,YourService>(),
                    Component.For<ILogger,DummyLogger>()
                    );
            }
        }
    }
    

    最后,编辑 YourService.svc 的标记以指定 Windsor 应创建服务实例:

    <%@ ServiceHost Language="C#" 
        Service="WcfService1.YourService" 
        CodeBehind="YourService.svc.cs" 
        Factory="Castle.Facilities.WcfIntegration.DefaultServiceHostFactory, Castle.Facilities.WcfIntegration" 
        %>
    

    现在您可以在服务的构造函数中将 ILogger 作为参数。 Windsor 将创建服务的每个实例,并为构造函数提供该参数。

    我几乎将它用于我创建的每个 WCF。


    您的评论提到您使用 Ninject。我找到了this documentation,它展示了如何将 Ninject 与 WCF 连接起来。

    几乎一模一样。服务的标记如下所示:

    <%@ ServiceHost Language="C#" 
        Service="WcfService1.YourService" 
        CodeBehind="YourService.svc.cs" 
        Factory="Ninject.Extensions.Wcf.NinjectServiceHostFactory" 
        %>
    

    然后是 Windsor 安装程序的 Ninject 等效项:

    public class WCFNinjectModule : NinjectModule
    {
        public override void Load()
        {
            Bind<ILogger>().To<DummyLogger>();
        }
    }
    

    然后在global.asax

    public class Global : NinjectWcfApplication
    
    protected override IKernel CreateKernel()
    {
        return new StandardKernel(new WCFNinjectModule());
    }
    

    唯一看起来不对的是你必须从NinjectWcfApplication 继承。在global.asax。这似乎有点侵入性。

    【讨论】:

    • 感谢您的建议。我会仔细研究它。虽然,我已经在使用 Ninject IoC,但我不确定使用两个不同的 IoC 是否好
    • 你不能使用两个,因为任何创建你的服务都会创建一切。 (我想你可以,但这将是一个没有任何好处的并发症。)我没有使用过 Ninject,但我查看了文档,配置几乎相同。我喜欢时不时地使用不同的代码,以确保我不会编写依赖于特定代码的代码。容器应该是“不可见的”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多