Search code examples
dependency-injectioncastle-windsoraspnetboilerplateasp.net-boilerplate

How to Call Application service from Web Api in ASP.Net Boilerplate MVC project?


ASP.NET Boilerplate (.Net Framework v4.7.2 & MVC)

I am creating a web api controller(AgentInfoController) for an application service class(AgentInfoAppService), which depends on a repository IAgentInfoRepository. From AgentInfoController, I am able to call a method from AgentInfoAppService by passing IAgentInfoRepository in the constructor like this new AgentInfoAppService(_agentInfoRepository).GetAgentCampaignswithCode but I am not sure if this is the correct way?

We have a working code from mvc layer where we call application service class(dynamic web api layer) without adding any references to Repository like below. Is there a way we could add a dependency injection so I don't have to add the repository in each application service calls from web api layer?Please advise.

jQuery.ajax({
    url: "/api/services/app/AgentInfoAppService/GetAgentCampaignswithCode?agentCode=100",
    type: "GET",
    contentType: "application/json; charset=utf-8"
})

public class AgentInfoAppService : ApplicationService, IAgentInfoAppService
{
    private readonly IAgentInfoRepository _agentInfoRepository;

    public AgentInfoAppService(IAgentInfoRepository agentInfoRepository)
    {
        _agentInfoRepository = agentInfoRepository;
    }

     public GetAgentCodeCampaignOutput GetAgentCampaignswithCode(string agentCode, bool? defaultCampaign)
    {
        var agentCampaigns = _agentInfoRepository.GetAgentCampaignswithCode(agentCode, defaultCampaign);
        return new GetAgentCodeCampaignOutput()
        {
            AgentCodeCampaign = Mapper.Map<List<AgentCodeCampaignDto>>(agentCampaigns)
        };
    }
}

 public class AgentInfoController : AbpApiController
{

    private readonly IAgentInfoRepository _agentInfoRepository;

    [HttpGet]
    public GetAgentCodeCampaignOutput GetAgentCampaignswithCode(string agentCode, bool? defaultCampaign)
    {
        return new AgentInfoAppService(_agentInfoRepository).GetAgentCampaignswithCode(agentCode, defaultCampaign);
    }
}

Solution

  • When you run the project Abp creates all Methods from ApplicationService layer and you can use it. You don't need to create the method again in the controller.

    Here is an example of what I'm saying

    I have an ApplicationServie method like this

    public class CiudadAppService : AsyncCrudAppService<AdozonaCiudad, CiudadDto, int, PagedAndSortedRequest, CiudadDto, CiudadDto>, ICiudadAppService
    {
    
        private readonly ICiudadManager _ciudadManager;
        public CiudadAppService(IRepository<AdozonaCiudad> repository, ICiudadManager ciudadManager) : base(repository)
        {
            _ciudadManager = ciudadManager;
        }
    
        public override async Task<CiudadDto> CreateAsync(CiudadDto input)
        {
    
            var result = await _ciudadManager.RegistrarOActualizar(ObjectMapper.Map<AdozonaCiudad>(input));
    
            return MapToEntityDto(result);
        }
    }
    

    In this AppService I have one Method called CreateAsync this method can be used from javascript like this.

    (function ($) {
    
    var _ciudadService = abp.services.app.ciudad;
    var _$form = $('form[name=Index]');
    
    function save() {
    
        _$form.validate({
            invalidHandler: function (form, validator) {
                var errors = validator.numberOfInvalids();
                if (errors) {
                    var firstInvalidElement = $(validator.errorList[0].element);
                    $('html,body').scrollTop(firstInvalidElement.offset().top - 100);
                    firstInvalidElement.focus();
                }
            },
    
            rules: {
                Ciudad: "required"
            },
            messages: {
                Ciudad: "El valor del campo es requerido"
            },
            highlight: function (element) {
                $(element).parent().addClass('error-validation')
            },
            unhighlight: function (element) {
                $(element).parent().removeClass('error-validation')
            }
        });
    
        if (!_$form.valid()) {
            return;
        }
    
        var ciudad = _$form.serializeFormToObject(); //serializeFormToObject is defined in main.js
    
        abp.ui.setBusy(_$form);
        _ciudadService.create(ciudad).done(function () {
            location.reload(true); //reload page to see edited role!
            abp.notify.success('Registro correcto');
            $(".save-button").html('Guardar');
        }).always(function () {
            abp.ui.clearBusy(_$form);
        });
    }
    }
    

    As you can see there the important part is: var _ciudadService = abp.services.app.ciudad; with this you're creating a service and you can access to all the methods that you have in ApplicationService

    I hope it could help you, if you need further help please leave a comment!