Может ли служба WCF иметь конструкторы?
Когда я снова создаю службу WCF в своем решении, могу ли я сделать следующее, у меня есть конструктор с параметром? Если да, как, когда и где время выполнения заполняет мой требуемый объект IBusinessLogic?
[ServiceContract]
public interface IServiceContract
{
[OperationContract]
...
}
public class MyService : IServiceContract
{
IBusinessLogic _businessLogic;
public ServiceLayer(IBusinessLogic businessLogic)
{
_businessLogic = businessLogic;
}
...
}
Ответы
Ответ 1
Из окна WCF будет использоваться только конструктор по умолчанию, вы не можете использовать параметризованные конструкторы. Вы должны сделать немного дополнительной работы, чтобы сделать конструкторы WCF с параметрами.
Вы можете попробовать следующее:
Как передать значения конструктору в моей службе wcf?
Ответ 2
Посмотрите ServiceHostFactory.
Ответ 3
Вы можете получить WCF (косвенно) вызов нестандартных конструкторов, для этого вам нужно будет свернуть собственный поставщик экземпляров. Вам нужно будет реализовать IInstanceProvider и добавить настраиваемое поведение службы. Некоторые ссылки, которые покажут вам, как это сделать в сочетании с Spring.NET:
Инъекция зависимостей службы WCF
Пример кода Инъекция зависимостей службы WCF
Ответ 4
Другим случаем, помимо других ответов, является создание службы singleton - это когда вы передаете экземпляр своей службы в ServiceHost (в отличие от типа);
Очевидно, что при создании экземпляра вы можете использовать любой конструктор;
Этот подход потребует добавления атрибута к вашей службе: [ServiceBehavior (InstanceContextMode.Single)];
Ответ 5
Вы должны реализовать IInstanceProvider, чтобы иметь возможность вызвать параметризованный конструктор службы. Этот конструктор не будет доступен в сгенерированном прокси.
Ответ 6
Я перефразировал решение @Mark Seemann как поведение поставщика общего экземпляра экземпляра.
Как использовать его:
var host = new ServiceHost(typeof(MyService), baseAddress);
var instanceProvider = new InstanceProviderBehavior<T>(() => new MyService(businessLogic));
instanceProvider.AddToAllContracts(host);
Код InstanceProviderBehavior:
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
}