2

家の中にNinjectの専門家はいますか?:)最近、WCFサービスアプリケーションとWindowsフォームクライアントアプリケーションをCastleWindsorの依存性注入からNinjectに変換しようとしています。

Win Forms側ではすべてうまくいきましたが、WCF側で問題が発生しています。私はこれまでに、Ninjectで利用可能なWCF拡張機能を使用して、私が実行および参照したWCFでDIを使用する必要があると考えていますが、サービスを解決しようとすると問題が発生すると考えています。

System.InvalidOperationException:タイプ'WcfMemberService'、ServiceHostディレクティブでService属性値として提供されているか、構成要素system.serviceModel / serviceHostingEnvironment/serviceActivationsで提供されているものが見つかりませんでした。

私が持っているコードは、たとえば私のWcfMemberServiceにアクセスするのに正しいと思ったもので、次のとおりです。

ServiceModule.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 WcfExtensionsGitHubページに掲載されているTimeServiceサンプルソリューションから採用しています

誰かが私がここで間違ったことをしたこと、そしてなぜ「WcfMemberService」が解決されないのかを知ることができますか?カーネルでは「WcfMemberService」にバインドされ、@ServiceHost宣言で参照されます。他に何が間違っているのかわかりません。これは、構文が大きく異なることを除いて、Castle Windsorで宣言する方法とまったく同じですNamed()が、ファイルのService部分でその名前を使用し、両方とも参照し.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 に答える