Search code examples
wcfsoapaspnetboilerplateasp.net-boilerplate

How to invoke an IApplicationService into a WCF SOAP services in abp Boilerplate?


I developed a MVC application using abp boilerplate and now I have the necessity to expose some services via WFC/SOAP.

The idea is to create a WFC Service, inject the required IApplicationService and use it.

Something like:

// 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);
    }
}

But this code does not work. :-(

The first error I have is from WCF saying the Service does not have a default constructor without parameters. So I am on the wrong way.

How can I inject the service into the SOAP service?

The answer https://stackoverflow.com/a/46048289/752004 did not help me.


Solution

  • Abp uses the Castle Windsor, so following the suggestions from this answer and this article I found the solution.

    1. Once imported the nuget package Castle.WcfIntegrationFacility, I created a new WCF library and in it I created a AbbModule class where I registered MyService (defined in pt. 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")
            );
        }
    }
    
    1. Then I created my IMyService interface (note that it extends ITransientDependency):
    [ServiceContract]
    public interface IMyService : ITransientDependency {
        [OperationContract]
        CourseDto GetCourse(int courseId);
    }
    
    1. Finally I implemented the interface with a constructor using injection:
    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;
            });
        }
    
    }