Как внедрить зависимость от службы WCF, используемой в качестве службы RESTFul, в среде selfhost - PullRequest
1 голос
/ 30 января 2020

Мне нужен пример того, как реализовать службу RESTfull с технологией WCF в среде с собственным хостом и с использованием контейнера DI (возможно, SimpleInjector).

Вкл. https://simpleinjector.readthedocs.io/en/latest/wcfintegration.html я нашел, как интегрировать пользовательскую фабрику, но это сделано для ServiceHost, но это не подходит для службы RESTFull, которая вместо этого использует WebServiceHost?

Я попытался настроить хост службы для совместимости с webHttpBinding, но ничего не произошло, и я получить такой вид ошибки:

<Fault
    xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none">
    <Code>
        <Value>Sender</Value>
        <Subcode>
            <Value
                xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:DestinationUnreachable
            </Value>
        </Subcode>
    </Code>
    <Reason>
        <Text xml:lang="it-IT">Impossibile elaborare nel destinatario il messaggio con To 'http://localhost:8733/3AdispPushBatchService/pushpost' a causa di una mancata corrispondenza AddressFilter in EndpointDispatcher. Controllare la corrispondenza di EndpointAddresses del mittente e del destinatario.</Text>
    </Reason>
</Fault>

Есть еще один пакет интеграции для WebServiceHost?

Это пример, который я сделал

AAADispPushBatchService.cs

using System;
using System.Configuration;
using System.IO;
using System.ServiceModel.Activation;
using System.Text;
using Newtonsoft.Json;
namespace AAARestService
{
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class AAADispPushBatchService : IAaaDispPushBatchService
    {
        public string GetBatchJson(Stream jsonFileContent)
        {
            try
            {
                var sr = new StreamReader(jsonFileContent, Encoding.UTF8);
                var str = sr.ReadToEnd();


                if (String.IsNullOrWhiteSpace(str))
                    throw new ArgumentException("No data inside body request");
                var definition = new { BatchName = "" };
                var json = JsonConvert.DeserializeAnonymousType(str, definition);
                if (json == null)
                    throw new ArgumentException("No valid json inside");
                if (String.IsNullOrWhiteSpace(json.BatchName))
                    throw new ArgumentException("BatchName not present");

                var currentDir = ConfigurationManager.AppSettings["BatchPath"];
                Directory.CreateDirectory(currentDir);

                var filepath = Path.Combine(currentDir, json.BatchName+".json");

                File.WriteAllText(filepath, str);

                return $"Saved in {filepath}";
            }
            catch (Exception e)
            {
                return e.Message;
            }
        }
    }
}

IAaaDispPushBatchService.cs

using System.IO;
using System.ServiceModel;
using System.ServiceModel.Web;

namespace AAARestService
{  
    [ServiceContract(Name = "AAADispPushBatchService")]
    public interface IAaaDispPushBatchService
    {
        [OperationContract]
        [WebInvoke(Method = "POST", UriTemplate = "pushpost", BodyStyle = WebMessageBodyStyle.Bare,ResponseFormat = WebMessageFormat.Json)]
        string GetBatchJson(Stream jsonFileContent);
    }
}

РЕДАКТИРОВАТЬ !!!!! Кстати, я пытаюсь добавить simpleinjector, вот пример, основанный на том, что я нашел в блоге

Bootstrapper.cs

using System.Reflection;
using SimpleInjector;

namespace AAARestService
{
    public static class BootStrapper
    {
        public static readonly Container Container;

        static BootStrapper()
        {
            Container container = new Container();


            container.Register<IMyDateTimeService,MyDAteTimeService>();

            container.RegisterWcfServices(Assembly.GetExecutingAssembly());

            Container = container;
        }
    }
}

MyWebServiceHostFactory.cs

public class MyWebServiceHostFactory : SimpleInjectorServiceHostFactory
    {
        public ServiceHost GetWebServiceEndpoint(Type serviceType,Uri baseAddress)
        {

            Uri[] addresses=new Uri[]{baseAddress};

            var service = CreateServiceHost(serviceType, addresses);

            ServiceEndpoint sep = service.AddServiceEndpoint(typeof(IAaaDispPushBatchService), new WebHttpBinding(), baseAddress);
            sep.EndpointBehaviors.Add(new WebHttpBehavior());

            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            service.Description.Behaviors.Add(smb);


            return service;
        }

        protected override ServiceHost CreateServiceHost(Type serviceType,
            Uri[] baseAddresses)
        {
            var host = new SimpleInjectorServiceHost(
                BootStrapper.Container,
                serviceType,
                baseAddresses);

            return host;
        }
    }

Main

static void Main(string[] args)
        {
            try
            {
                Uri httpUrl = new Uri("http://localhost:8733/3AdispPushBatchService");
                Uri httpUrl1 = new Uri("http://localhost:8734/3AdispPushBatchService");
                //ServiceHost selfhost = new ServiceHost(typeof(AAADispPushBatchService), httpUrl);

                //ServiceEndpoint sep =selfhost.AddServiceEndpoint(typeof(IAaaDispPushBatchService),new WebHttpBinding(), httpUrl);
                //sep.EndpointBehaviors.Add(new WebHttpBehavior());



                //ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                //smb.HttpGetEnabled = true;
                //selfhost.Description.Behaviors.Add(smb);


                MyWebServiceHostFactory factory = new MyWebServiceHostFactory();
                var selfhost=factory.GetWebServiceEndpoint(typeof(AAADispPushBatchService), httpUrl);


                selfhost.Open();

                //WebServiceHost webHost = new WebServiceHost(typeof(AAADispPushBatchService),httpUrl1);
                //webHost.Open();

                foreach (ServiceEndpoint se in selfhost.Description.Endpoints)
                    Console.WriteLine("Service is host with endpoint " + se.Address);
                //foreach (ServiceEndpoint se in webHost.Description.Endpoints)
                //    Console.WriteLine("Service is host with endpoint " + se.Address);

                //Console.WriteLine("ASP.Net : " + ServiceHostingEnvironment.AspNetCompatibilityEnabled);
                Console.WriteLine("Host is running... Press <Enter> key to stop");
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadLine();
            }
        }

1 Ответ

0 голосов
/ 31 января 2020

Я не пробовал интегрироваться с WCF с использованием технологии внедрения зависимостей, возможно, решение в этом блоге стоит попробовать. Я также не рекомендую использовать внедрение зависимостей в WCF, поскольку оно не поддерживает внедрение зависимостей изначально. Кроме того, для servicehost хостинга WCF REST-style сервисов нам необходимо добавить поведение WebHttp на конечной точке сервиса. Пожалуйста, обратитесь к следующей реализации кода.

   Uri uri = new Uri("http://localhost:8004");
            WebHttpBinding binding = new WebHttpBinding();
            binding.Security.Mode = WebHttpSecurityMode.None;

            using (ServiceHost sh = new ServiceHost(typeof(MyService), uri))
            {
                ServiceEndpoint se=sh.AddServiceEndpoint(typeof(IService), binding,"");
                se.EndpointBehaviors.Add(new WebHttpBehavior());

                sh.Opened += delegate
                {
                    Console.WriteLine("Service is ready");
                };
                sh.Closed += delegate
                {
                    Console.WriteLine("Service is clsoed");
                };
    sh.Open();
                Console.ReadLine();
                //pause
                sh.Close();
                Console.ReadLine();

Не стесняйтесь, дайте мне знать, если есть что-то, с чем я могу помочь.

...