2

家里有 Ninject 专家吗?:) 我最近一直在尝试将我的 WCF 服务应用程序和 Windows 窗体客户端应用程序从 Castle Windsor 依赖注入转换为 Ninject。

在 Win Forms 方面一切都很好,但我在 WCF 方面遇到了问题。到目前为止,我已经了解到,我相信我需要可用于 Ninject 的 WCF 扩展,以便将 DI 与 WCF 一起使用,我已经完成并引用了但仍然遇到我认为在尝试解决我的服务时遇到的问题:

System.InvalidOperationException:找不到类型“WcfMemberService”,作为 ServiceHost 指令中的服务属性值提供,或在配置元素 system.serviceModel/serviceHostingEnvironment/serviceActivations 中提供。

我拥有的代码是我认为可以正确访问的代码,例如我的 WcfMemberService 如下:

服务模块.cs:

public class ServiceModule : NinjectModule
{
    private IKernel _parentContainer;
    public ServiceModule(IKernel container)
    {
    this._parentContainer = container;
    }

    public override void Load()
    {
    Bind<IDataContextProvider>().To<DataContextProvider>()
        .WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString);
    Bind(typeof(IRepository<>)).To(typeof(Repository<>));
    Bind<IServiceLocator>().ToConstant(new NinjectServiceLocator(_parentContainer));
    Bind<IUserService>().To<UserService>();

    // ** WCF Services **
    Bind<Business.Common.Wcf.Services.Contracts.IMemberServiceContract>().To<Business.Common.Wcf.Services.MemberService>().InSingletonScope().Named("WcfMemberService");
    }
}

我所做的假设是,从我的工作 Castle Windsor 配置转换过来时,它Named()应该与 WCF.svc文件声明中的条目相同。所以我这样做如下:

<%@ ServiceHost Language="C#" Service="WcfMemberService" Factory="Ninject.Extensions.Wcf.NinjectServiceHostFactory" %>

非常简单,顺便说一下,我从 Ninject Wcf Extensions GitHub 页面上的 TimeService 示例解决方案中采用了这种方法。

谁能看到我在这里做错了什么以及为什么“WcfMemberService”无法解决?它在内核中必然是“WcfMemberService”,并在@ServiceHost 声明中被引用。我看不出还有什么问题。这与我在 Castle Windsor 中声明它的方式完全相同,只是语法大致不同,但两者Named()都在文件的服务部分中使用和引用该名称.svc

*更新*我发现如果我不使用该Named()方法,只需在@ ServiceHost声明中设置我的服务即可Business.Common.Wcf.Services.MemberService, Business.Common.Wcf.Services。但我仍然对为什么我不能使用命名服务感到困惑。谢谢。

顺便说一句,我的 Ninject 模块是通过Global.asax.cs以下方式加载的:

public class Global : NinjectWcfApplication
{
    #region Overrides of NinjectWcfApplication

    /// <summary>
    /// Creates the kernel that will manage your application.
    /// </summary>
    /// <returns>The created kernel.</returns>
    protected override IKernel CreateKernel()
    {
        // config to reside in executing directory
        log4net.Config.XmlConfigurator.Configure(new FileInfo("log4net.config"));
        var _container = new StandardKernel();
        _container.Load(new ServiceModule(_container));
        //_container.Load(new Log4netModule());
        ServiceLocator.SetLocatorProvider(() => _container.Get<IServiceLocator>());

        return _container;
    }

    #endregion
}
4

1 回答 1

2

.Named(string) 语法用于条件绑定。例如,如果您有

Bind<IService1>().To<MyService>().Named("MyServiceImpl");
Bind<IService1>().To<DefaultService();

然后 DefaultService 将作为默认值注入,除非您有以下内容:

class MyForm([Named("MyServiceImpl")] IService1 service){...}

或者

kernel.Get<IService1>(metadata => metadata.Name == "MyServiceImpl");

或者

kernel.Get<IService1>("MyServiceImpl");

如果您没有该类型的默认绑定,并且您只有条件命名绑定,那么当您尝试创建实例时,您将收到激活异常。

-伊恩

于 2010-11-01T16:51:25.973 回答