Как вызвать IApplicationService в сервисы WCF SOAP в abp Boilerplate? - PullRequest
0 голосов
/ 31 декабря 2018

Я разработал приложение MVC, используя шаблон abp, и теперь у меня есть необходимость предоставлять некоторые службы через WFC / SOAP.

Идея состоит в том, чтобы создать службу WFC, внедрить требуемую IApplicationService и использовать ее..

Что-то вроде:

// this code does not work
public class MyFirstService : IMyFirstService, ITransientDependency {
    private readonly ICourseAppService _courseAppService;

    // Injection here does not work!
    public MyFirstService(ICourseAppService courseAppService) {
        _courseAppService = courseAppService;
    }

    public CourseDto GetData(int id) {
        return _courseAppService.Get(id);
    }
}

Но этот код не работает.: - (

Первая ошибка, с которой я столкнулся, связана с WCF , в котором говорится, что у службы нет конструктора по умолчанию без параметров. Поэтому я ошибаюсь.

Как я могу внедрить службу в службу SOAP?

Ответ https://stackoverflow.com/a/46048289/752004 мне не помог.

Ответы [ 2 ]

0 голосов
/ 05 января 2019

Abp использует Castle Windsor, поэтому, следуя советам этого ответа и этой статьи Я нашел решение.

  1. После импорта пакета nuget Castle.WcfIntegrationFacility , я создал новую библиотеку WCF и в ней я создал класс AbbModule, в котором я зарегистрировал MyService (определено в разделе 3):
[DependsOn(typeof(BookingCoreModule), typeof(BookingApplicationModule))]
public class BookingSoapModule : AbpModule {

    public override void Initialize() {
        IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());

        IocManager.IocContainer.AddFacility<WcfFacility>().Register(
            Component
                .For<IMyService>()
                  .ImplementedBy<MyService>()
                  .Named("MyService")
        );
    }
}
Затем я создал свой IMyService интерфейс (обратите внимание, что он расширяет ITransientDependency):
[ServiceContract]
public interface IMyService : ITransientDependency {
    [OperationContract]
    CourseDto GetCourse(int courseId);
}
Наконец-то я реализовал интерфейс с конструктором, использующим инъекцию :
public class MyService : IMySecondService {

    private readonly ICourseAppService _courseAppService;
    public IAbpSession AbpSession { get; set; }
    public ILogger Logger { get; set; }

    public MyService(ICourseAppService courseAppService) {
        AbpSession = NullAbpSession.Instance;
        Logger = NullLogger.Instance;

        _courseAppService = courseAppService;
    }

    public CourseDto GetCourse(int courseId) {
        AsyncHelper.RunSync(async () => {
            var course = await _courseAppService.Get(courseId);
            return course;
        });
    }

}
0 голосов
/ 01 января 2019

WCF использует Reflection для создания экземпляра службы, поэтому, если у вашей службы нет конструктора без параметров, wcf не сможет создать экземпляр службы, поэтому wcf выдает ошибку.

Интегрировать внедрение нелегкофреймворк с wcf.

Вы должны настроить провайдера экземпляра (который предоставляет экземпляр сервиса wcf).

https://blogs.msdn.microsoft.com/carlosfigueira/2011/05/31/wcf-extensibility-iinstanceprovider/

В своем провайдере настраиваемого экземпляра вы можете предоставить свою внедренную услугуэкземпляр в методе GetInstance.

Затем вы должны заставить wcf использовать свой собственный поставщик экземпляра, используя поведение службы.

Например,

 public class MyServiceAttribute : Attribute, IServiceBehavior
{
    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {

    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        foreach (ChannelDispatcher item in serviceHostBase.ChannelDispatchers)
        {
            foreach (EndpointDispatcher item1 in item.Endpoints)
            {
                item1.DispatchRuntime.InstanceProvider = new MyInstanceProvider(); // apply customized instanceProvider
            }
        }
    }

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {

    }
}

Затем вы должны настроить ServiceHost наприменить сервисное поведение.Как и

 public class MyUnityServiceHost : ServiceHost
{

    protected MyUnityServiceHost()
    {
    }

    protected override void OnOpening()
    {
        base.OnOpening();
        if (this.Description.Behaviors.Find<MyServiceAttribute >() == null)
        {
            this.Description.Behaviors.Add(new MyServiceAttribute ());//add your behavior
        }
    }
}

Наконец, вы должны настроить HostFactory, чтобы создать свой собственный сервис-хост.https://blogs.msdn.microsoft.com/carlosfigueira/2011/06/13/wcf-extensibility-servicehostfactory/

Вы можете сослаться на подобное обсуждение ниже.

Внедрение данных в службу WCF

...