How can I implement IOrganizationService in ASP.NET Core?

276 views Asked by At

I have an ASP.NET Core 7 project that I use to connect to Dynamics 365 / Dataverse.

I do not use any services or interfaces as of now. In each controller I am creating a new instance of a ServiceClient using Microsoft.PowerPlatform.Dataverse.Client.

For example:

public class ContactsController : Controller
{
    private readonly IConfiguration _configuration;

    public ContactsController(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    [Authorize]
    public IActionResult Index()
    {
        string? connectionString = _configuration.GetConnectionString("Dataverse");

        using (ServiceClient svc = new ServiceClient(connectionString))
        {
            if (svc.IsReady)
            {
                //Get data from Dataverse using svc
                return View();
            }

            return View();
        }
    }
}

However, I know this approach is not good. I am not re-using the ServiceClient and creating new ones for every call in each controller. I know that I should register the ServiceClient and IOrganizationService in Program.cs like this for example:

builder.Services.AddScoped<IOrganizationService, ServiceClient>();

But I don't know how to write the interface and service class for this and how to add the connection string.

3

There are 3 answers

0
Jalpa Panchal On BEST ANSWER

You could try using below code that the will create the ServiceClient and abstracts away the direct usage of ServiceClient in your controllers.

IOrganizationServiceWrapper.cs:

public interface IOrganizationServiceWrapper
{
    bool IsReady { get; }
    .......
    .......
}

OrganizationServiceWrapper.cs:

public class OrganizationServiceWrapper : IOrganizationServiceWrapper
{
    private readonly ServiceClient _serviceClient;

    public OrganizationServiceWrapper(string connectionString)
    {
        _serviceClient = new ServiceClient(connectionString);
    }

    public bool IsReady => _serviceClient.IsReady;
    
    ...
    ...
}

Program.cs:

builder.Services.AddScoped<IOrganizationServiceWrapper>(sp => 
{
    var configuration = sp.GetRequiredService<IConfiguration>();
    var connectionString = configuration.GetConnectionString("Dataverse");
    return new OrganizationServiceWrapper(connectionString);
});

ContactsController.cs:

public class ContactsController : Controller
{
    private readonly IOrganizationServiceWrapper _orgService;

    public ContactsController(IOrganizationServiceWrapper orgService)
    {
        _orgService = orgService;
    }

    [Authorize]
    public IActionResult Index()
    {
        if (_orgService.IsReady)
        {
            return View();
        }
        return View();
    }
}
0
Poja On

FYI. Added more methods like the following:

IOrganizationServiceWrapper.cs

public interface IOrganizationServiceWrapper
{
    bool IsReady();
    public EntityCollection RetrieveMultiple(QueryExpression query);
    public Task<Entity> RetrieveAsync(string Entityname, Guid id, ColumnSet columnSet);
    public void Update(Entity contact);
}

OrganizationServiceWrapper.cs

public class OrganizationServiceWrapper : IOrganizationServiceWrapper
{
    private readonly ServiceClient _serviceClient;
    private QueryExpression query;

    public OrganizationServiceWrapper(string connectionString)
    {
        _serviceClient = new ServiceClient(connectionString);
    }

    public bool IsReady()
    {
        return _serviceClient.IsReady;
    }

    public EntityCollection RetrieveMultiple(QueryExpression query)
    {
        return _serviceClient.RetrieveMultiple(query);
    }

    public void Update(Entity contact)
    {
        _serviceClient.Update(contact);
    }

    public Task<Entity> RetrieveAsync(string Entityname, Guid id, ColumnSet columnSet)
    {
       return _serviceClient.RetrieveAsync(Entityname, id, columnSet);
    }
}
1
ssedlacek On

I am not sure why are you creating wrapper for IOrganizationService, if you are just copying what's already there. If you want to use Dependency Injection for the ServiceClient registered in Program.cs, just do this: Program.cs

builder.Services.AddScoped<IOrganizationService>(sp => 
{
    var configuration = sp.GetRequiredService<IConfiguration>();
    var connectionString = configuration.GetConnectionString("Dataverse");
    return new ServiceClient(connectionString);
});

And you're good to go in your controllers like this:

public class ContactsController : Controller
{
    private readonly IOrganizationService _crmService;

    public ContactsController(IOrganizationService crmService)
    {
        _crmService = crmService;
    }

    [Authorize]
    public IActionResult Index()
    {
        // Do CRUD operations with _crmService etc..

        return View();
    }
}