ソリューションにWCFサービスを新しく追加するときに、次のことを実行できます。パラメーターを渡してコンストラクターを渡せますか?はいの場合、どのように、いつ、どこで、ランタイムが必要なIBusinessLogicオブジェクトに入力しますか?
[ServiceContract]
public interface IServiceContract
{
[OperationContract]
...
}
public class MyService : IServiceContract
{
IBusinessLogic _businessLogic;
public ServiceLayer(IBusinessLogic businessLogic)
{
_businessLogic = businessLogic;
}
...
}
デフォルトでは、WCFは既定のコンストラクターのみを使用し、パラメーター化されたコンストラクターは使用できません。 WCF呼び出しのパラメーター化されたコンストラクターを作成するには、少し余分な作業を行う必要があります。
あなたはこれを試すことができます:
WCFに(間接的に)非既定のコンストラクターを呼び出させることができます。そのためには、独自のインスタンスプロバイダーをロールする必要があります。 IInstanceProviderを実装し、カスタムサービス動作を追加する必要があります。 Spring.NETと組み合わせてこれを行う方法を示すいくつかのリンク:
ServiceHostFactory を見てください。
他の応答に加えて、シングルトンサービスを作成する場合-これは、サービスのインスタンスを(タイプではなく)ServiceHostに渡す場合です。
もちろん、インスタンスを作成するときには、どのコンストラクターでも使用できます。
このアプローチでは、サービスに属性を追加する必要があります:[ServiceBehavior(InstanceContextMode.Single)];
@Mark Seemannのソリューションをgeneric instance provider behaviorと言い換えました。
var Host = new ServiceHost(typeof(MyService), baseAddress);
var instanceProvider = new InstanceProviderBehavior<T>(() => new MyService(businessLogic));
instanceProvider.AddToAllContracts(Host);
public class InstanceProviderBehavior<T> : IInstanceProvider, IContractBehavior
where T : class
{
private readonly Func<T> m_instanceProvider;
public InstanceProviderBehavior(Func<T> instanceProvider)
{
m_instanceProvider = instanceProvider;
}
// I think this method is more suitable to be an extension method of ServiceHost.
// I put it here in order to simplify the code.
public void AddToAllContracts(ServiceHost serviceHost)
{
foreach (var endpoint in serviceHost.Description.Endpoints)
{
endpoint.Contract.Behaviors.Add(this);
}
}
#region IInstanceProvider Members
public object GetInstance(InstanceContext instanceContext, Message message)
{
return this.GetInstance(instanceContext);
}
public object GetInstance(InstanceContext instanceContext)
{
// Create a new instance of T
return m_instanceProvider.Invoke();
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
try
{
var disposable = instance as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
catch { }
}
#endregion
#region IContractBehavior Members
public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
{
dispatchRuntime.InstanceProvider = this;
}
public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
{
}
#endregion
}
パラメータ化されたサービスコンストラクターを呼び出せるようにするには、IInstanceProviderを実装する必要があります。このコンストラクタのうち、生成されたプロキシでは使用できません。