Как вызвать IApplicationService в сервисы WCF SOAP в abp Boilerplate?
Я разработал приложение 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?
Ответ /questions/38532303/kak-rabotat-s-servisami-wcf-v-aspnet-boilerplate/38532317#38532317 мне не помог.
2 ответа
Abp использует Виндзорский замок, поэтому, следуя предложениям из этого ответа и этой статьи, я нашел решение.
- После импорта пакета https://www.nuget.org/packages/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;
});
}
}
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/
Вы можете сослаться на подобное обсуждение ниже.