Можно ли создать экземпляр WebServiceHost через экземпляр типа службы без конструктора без параметров? - PullRequest
2 голосов
/ 03 апреля 2012

Я пытаюсь создать собственный хост System.ServiceModel.Web.WebServiceHost (.NET 4), однако у меня возникла проблема с конструктором.Есть три варианта:

  1. WebServiceHost() конструктор без параметров, который кажется бессмысленным, поскольку нет способа указать тип службы или даже контракт.Размышляя об этом, он ничего не делает - просто пустой конструктор по умолчанию, который не вызывает base.

  2. WebServiceHost(object singletonInstance, params Uri[] baseAddresses) Мне не нужен экземпляр-одиночка, так как этоInstanceContextMode.PerCall class.

  3. WebServiceHost(System.Type serviceType, params Uri[] baseAddresses) Тип, который я хочу создать в качестве службы, не имеет конструктора без параметров (что является требованием этого метода).Я использую NInject, чтобы вставить параметры в конструктор.Тем не менее, я пытаюсь запустить это как самопроверку, поэтому я хочу избегать DI.

Есть ли какие-либо варианты в этих направлениях, или я не буду самостоятельно-host

1 Ответ

3 голосов
/ 03 апреля 2012

Для поддержки классов обслуживания без конструкторов без параметров вам нужно использовать реализацию IInstanceProvider, которая знает, как создать класс обслуживания.Код ниже показывает код с WebServiceHost, и вы можете найти больше информации о поставщиках экземпляров на http://blogs.msdn.com/b/carlosfigueira/archive/2011/05/31/wcf-extensibility-iinstanceprovider.aspx.

public class StackOverflow_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();
    }
}
...