WCFサービスに依存性注入を使用しようとしています。サービスはUnityコンテナに依存しています。コンテナは、IJob
インターフェイス(メソッド呼び出しのJobKey
パラメータに基づく)を実装する適切なクラスを見つけるために使用され、そのメソッドを呼び出します。WCFカスタムのServiceBehavior/InstanceProvider(パラメータのないコンストラクタ)
サービスはMVC2でホストされています。私は以下のスニペットから無関係なものをできるだけ省いています。必要に応じて利用できる完全なコード...私がこれまで行ってきた
何:
このMSDN Articleに基づいて、私は私のサービスをインスタンス化し、それにコンテナを渡す必要がありますカスタムInstanceProvider
を作成しました。
ServiceBehavior
を使用してInstanceProvider
を使用し、最後にBehaviorExtension
を使用してServiceBehavior
を返すように作成しました。
Public Class WCFDIInstanceProvider
Implements IInstanceProvider
Private ServiceType As Type
Private Property _Container As IUnityContainer
Private ReadOnly Property Container As IUnityContainer
Get
If _Container Is Nothing Then
_Container = InitialiseContainer()
End If
Return _Container
End Get
End Property
Public Sub New(ByVal ServiceType As Type)
Me.ServiceType = ServiceType
End Sub
Private Function InitialiseContainer() As IUnityContainer
'Code which scans assemblies and populates the container as appropriate
'I'm confident this code works as I've tested it elsewhere
Return Container
End Function
Public Function GetInstance(ByVal instanceContext As System.ServiceModel.InstanceContext) As Object Implements System.ServiceModel.Dispatcher.IInstanceProvider.GetInstance
Return GetInstance(instanceContext, Nothing)
End Function
Public Function GetInstance(ByVal instanceContext As System.ServiceModel.InstanceContext, ByVal message As System.ServiceModel.Channels.Message) As Object Implements System.ServiceModel.Dispatcher.IInstanceProvider.GetInstance
Return Container.Resolve(Me.ServiceType)
End Function
End Class
そしてServiceBehavior
:
Public Class WCFDIServiceBehavior
Implements IServiceBehavior
Public Sub ApplyDispatchBehavior(ByVal serviceDescription As System.ServiceModel.Description.ServiceDescription, ByVal serviceHostBase As System.ServiceModel.ServiceHostBase) Implements System.ServiceModel.Description.IServiceBehavior.ApplyDispatchBehavior
For Each ChannelDispatcherBase As ChannelDispatcherBase In serviceHostBase.ChannelDispatchers
Dim ChannelDispatcher As ChannelDispatcher = TryCast(ChannelDispatcherBase, ChannelDispatcher)
If ChannelDispatcher IsNot Nothing Then
For Each Dispatcher As EndpointDispatcher In ChannelDispatcher.Endpoints
Dispatcher.DispatchRuntime.InstanceProvider = New WCFDIInstanceProvider(serviceDescription.ServiceType)
Next
End If
Next
End Sub
そして最後に、本当に noddyでBehaviorExtension:
Public Class WCFDIBehaviorExtension
Inherits BehaviorExtensionElement
Public Overrides ReadOnly Property BehaviorType As System.Type
Get
Return GetType(WCFDIServiceBehavior)
End Get
End Property
Protected Overrides Function CreateBehavior() As Object
Return New WCFDIServiceBehavior
End Function
End Class
WCFコンフィグツールは、上記のすべてが好きのようですし、生成しましたConfig XMLに続いて:
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"
aspNetCompatibilityEnabled="true">
<serviceActivations>
<add relativeAddress="WebJob.svc"
service="MyApplication.WebJobService"
factory="System.ServiceModel.Activation.ServiceHostFactory" />
</serviceActivations>
</serviceHostingEnvironment>
<standardEndpoints>
<mexEndpoint>
<standardEndpoint name="WebJobServiceMex" />
</mexEndpoint>
</standardEndpoints>
<behaviors>
<serviceBehaviors>
<behavior name="WCFDIServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<WCFDIBehavior />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="WebJobService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="httpBinding"
name="HTTPEndpoint" contract="MyApplication.JobService.Common.IWebJobService" />
<endpoint binding="mexTcpBinding" bindingConfiguration="" name="mexEndpoint" />
</service>
</services>
私が得る例外は次のとおりです。
System.ServiceModel.ServiceActivationException:サービス '/MyAppDir/WebJob.svc' は コンパイル時に例外のために活性化することはできません。例外メッセージは次のとおりです。 のサービスタイプは、デフォルトの (パラメータなし)コンストラクタを持たないため、サービスとしてロードできませんでした。問題を解決するには、デフォルトの コンストラクターを型に追加するか、またはその型のインスタンスをホストに渡します。
System.InvalidOperationException:提供されたサービスタイプが、デフォルトの (パラメータなし)コンストラクタを持たないため、サービスとしてロードされない サービスタイプです。問題を解決するには、デフォルトの コンストラクターを型に追加するか、またはその型のインスタンスをホストに渡します。 ServiceBehaviorのInstaceProviderは、サービスをインスタンス化することはできませんデフォルト - それは私のカスタム
ServiceBehavior
を適用していないと仮定すると理にかなって
WebHost failed to process a request.
Sender Information: System.ServiceModel.ServiceHostingEnvironment+HostingManager/13982700
Exception: System.ServiceModel.ServiceActivationException: The service '/MyAppDir/WebJob.svc' cannot be activated due to an exception during compilation. The exception message is: The service type provided could not be loaded as a service because it does not have a default (parameter-less) constructor. To fix the problem, add a default constructor to the type, or pass an instance of the type to the host.. ---> System.InvalidOperationException: The service type provided could not be loaded as a service because it does not have a default (parameter-less) constructor. To fix the problem, add a default constructor to the type, or pass an instance of the type to the host.
at System.ServiceModel.Dispatcher.InstanceBehavior..ctor(DispatchRuntime dispatch, ImmutableDispatchRuntime immutableRuntime)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime..ctor(DispatchRuntime dispatch)
at System.ServiceModel.Dispatcher.DispatchRuntime.GetRuntimeCore()
at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpened()
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)
[Blah]
Process Name: w3wp
Process ID: 2108
。
注意事項:パラメータのないコンストラクタをサービスに追加すると、例外は発生しません(もちろん、コンテナも渡されません)ので、私はかなり自信があります問題の原因を見つけた
誰かが間違っていることを指摘できますか?
@Steven編集していただきありがとうございますが、私は例外ダンプがかなり明確だと思いました。クォート内のエラーメッセージを複製すると、実際に品質が向上しますか? – Basic
はい、私はそう信じています。例外メッセージのグーグルでこの質問を見つけましたが、質問をスキャンした後、私はこのメッセージを見つけることができませんでした。私の編集では、他の人がこのメッセージをより簡単に見つけることができます。それが私の目標です。 – Steven