2010-11-01 52 views
2

任何Ninject的家中的專家? :) 我最近一直試圖將我的WCF服務應用程序和Windows窗體客戶端應用程序從Castle Windsor依賴注入轉換爲Ninject。使用Ninject的WCF服務問題(從溫莎搬家)(InvalidOperationException)

所有在Win Forms方面都沒有問題,但我遇到了WCF方面的問題。我已經瞭解到目前爲止,我相信我需要爲Ninject提供WCF擴展,以便將DI與WCF一起使用,但我仍然遇到一個問題,我相信當我的服務嘗試解決時:

系統.InvalidOperationException:無法找到在ServiceHost指令中作爲Service屬性值提供的或在配置元素system.serviceModel/serviceHostingEnvironment/serviceActivations中提供的類型「WcfMemberService」。

我有這就是我認爲是正確的訪問剛剛例如我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" %> 

很簡單,我已經採取了從方式的特點WCF Ninject擴展GitHub的here頁面上的TimeService示例解決方案這種方式。

任何人都可以看到我在這裏做錯了什麼,爲什麼「WcfMemberService」不會解決?它肯定是內核中的「WcfMemberService」,並在@ServiceHost聲明中引用。我看不出還有什麼可能是錯的。這與我在Windsor Castle中聲明它的方式完全相同,除了大致不同的語法,但兩者都使用Named()並且都在.svc文件的Service部分中使用該名稱。

* 更新 *,如果我不使用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 
} 
+0

除非@Ian Davis是關於的,否則最好在Ninject郵件列表上詢問這種類型的東西。 – 2010-11-01 08:51:09

+0

謝謝Ruben,我今天早些時候在那裏問過,所以我們會看到會發生什麼:) – GONeale 2010-11-01 10:35:30

回答

2

的.Named(串)語法在條件結合使用。舉例來說,如果你有

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"); 

如果你沒有一個defa ult綁定類型,並且您只有條件命名綁定,那麼當您嘗試創建實例時,您將獲得激活異常。

-Ian

+0

感謝您解釋Named方法。所以最好的方法是直接在'@ ServiceHost'指令中引用類和程序集,正如我所說的那樣?然後就這樣運行? – GONeale 2010-11-02 04:40:06

+0

看起來您已經正確設置了其餘部分,因此您的服務應該正確注入其依賴關係。有一件事,你不應該給模塊內核實例,因爲當你擴展NinjectModule時,它應該作爲一個屬性提供。 – 2010-11-02 15:25:30