Можно ли создать экземпляр WebServiceHost через экземпляр типа службы без конструктора без параметров?
Я пытаюсь создать самостоятельно System.ServiceModel.Web.WebServiceHost
(.NET 4), однако у меня возникла проблема с конструктором. Есть три варианта:
WebServiceHost()
конструктор без параметров, который кажется бессмысленным, поскольку нет способа указать тип службы или даже контракт. Размышляя об этом, он ничего не делает - просто пустой конструктор по умолчанию, который не вызывает base.WebServiceHost(object singletonInstance, params Uri[] baseAddresses)
Я не хочу экземпляр синглтона, так как этоInstanceContextMode.PerCall
учебный класс.WebServiceHost(System.Type serviceType, params Uri[] baseAddresses)
Тип, который я хочу создать как сервис, не имеет конструктора без параметров (что является требованием этого метода). Я использую NInject, чтобы вставить параметры в конструктор. Тем не менее, я пытаюсь запустить этот тест как самостоятельный, поэтому я хочу избежать DI.
Есть ли какие-либо варианты в этом направлении, или мне придется не принимать самостоятельно?
1 ответ
Для поддержки классов обслуживания без конструкторов без параметров необходимо использовать IInstanceProvider
реализация, которая знает, как создать класс обслуживания. Код ниже показывает один с WebServiceHost
и вы можете узнать больше о поставщиках экземпляров по адресу http://blogs.msdn.com/b/carlosfigueira/archive/2011/05/31/wcf-extensibility-iinstanceprovider.aspx.
public class Stackru_9997163
{
[ServiceContract]
public class Service
{
private int increment;
public Service(int increment)
{
this.increment = increment;
}
[WebGet]
public int Add(int x, int y)
{
return x + y + increment;
}
}
class MyInstanceProvider : IInstanceProvider
{
Func<Service> serviceCreator;
public MyInstanceProvider(Func<Service> serviceCreator)
{
this.serviceCreator = serviceCreator;
}
public object GetInstance(InstanceContext instanceContext, Message message)
{
return this.serviceCreator();
}
public object GetInstance(InstanceContext instanceContext)
{
return this.serviceCreator();
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
}
}
class MyServiceBehavior : IServiceBehavior
{
Func<Service> serviceCreator;
public MyServiceBehavior(Func<Service> serviceCreator)
{
this.serviceCreator = serviceCreator;
}
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcher cd in serviceHostBase.ChannelDispatchers)
{
foreach (EndpointDispatcher ed in cd.Endpoints)
{
ed.DispatchRuntime.InstanceProvider = new MyInstanceProvider(this.serviceCreator);
}
}
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
}
public static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
WebServiceHost host = new WebServiceHost(typeof(Service), new Uri(baseAddress));
int currentIncrement = 1;
host.Description.Behaviors.Add(new MyServiceBehavior(delegate()
{
return new Service(currentIncrement++);
}));
host.Open();
Console.WriteLine("Host opened");
for (int i = 0; i < 10; i++)
{
WebClient c = new WebClient();
Console.WriteLine(c.DownloadString(baseAddress + "/Add?x=6&y=8"));
}
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}