mercredi 15 mars 2023

How can I inject named delegate function into a factory to resolve dependency in .net 7

I am working on a .net 7 c# solution. I have a class library that defines my base interface. Fo eg.

public interface IFoo<T1, T2> 
        where T1 : Contract1 where T2 : Contract2
    {
        Task<ResponseContract> Function1(
            T1 T1Object, 
            T2 T2Object);
    }

In other class libraries, I have defined the implementations for this interface

public class Bar1Contract1 : Contract1{}
public class Bar1Contract2 : Contract2{}
public interface IBar1 : IFoo<Bar1Contract1, Bar1Contract2>{}
public class Bar1 : IBar1{
    public async Task<ResponseContract> Function1(
                Bar1Contract1 T1Object, 
                Bar1Contract2 T2Object){
        //Do something and return ResponseContract
    }
}

public class Bar2Contract1 : Contract1{}
public class Bar2Contract2 : Contract2{}
public interface IBar2 : IFoo<Bar2Contract1, Bar2Contract2>{}
public class Bar2 : IBar2{
    public async Task<ResponseContract> Function1(
                Bar2Contract1 T1Object, 
                Bar2Contract2 T2Object){
        //Do something and return ResponseContract
    }
}

Then I have a separate service that needs to call Bar1 implementation or Bar2 implementation based on user request. My approach to this is that I have created a factory method to create the IFoo object in my class libraries where my services are determined

public class FooFactory{
private readonly Func<string, IFoo<Contract1, Contract2>> _fooFactory;

        public FooFactory(Func<string, IFoo<Contract1, Contract2>> fooFactory)
        {
            this._fooFactory = fooFactory;
        }

        public IFoo<Contract1, Contract2> CreateFoo(string input)
        {
            return _fooFactory(input);
        }
}

public interface IFooService(){
Task<ServiceContract1> ServiceFunction1(string input, Contract1 contract1, Contract2 contract2);
}

public class FooService(){
        private FooFactory _fooFactory;
        public FooService(FooFactory fooFactory){
                this._fooFactory = fooFactory;
        }
        public async Task<ServiceContract1> ServiceFunction1(string input, Contract1 contract1, Contract2 contract2){
                //do something
                var foo = this._fooFactory.CreateFoo(input);
                var response = await foo.Function1(contract1, contract2);
                // do something else and return serviceContract1
        }
}

Finally I have a web application project where I'm registering my dependencies in my Project.cs

Builder.Services.AddScoped<IBar1, Bar1>();
Builder.Services.AddScoped<IBar2, Bar2>();
Builder.Services.AddSingleton<FooFactory>();
Builder.Services.AddScoped<IFooService, FooService>();

In my controller, I have

[Route("api/[controller]")]
[ApiController]
public class FooController : ControllerBase
{
    IFooService _fooService;
    public FooController(IFooService fooService) { 
        this._fooService = fooService;
    }
    public async Task<ActionResult> Route1(ViewModel model){
        var response = await this._fooService.ServiceFunction1(model.input, model.Contract1, model.Contract2);
        return Ok(response);
    }
}

However, I'm unable to create a delegate function that resolves IFoo based on an input string and inject it in my Factory. Is there any other approach that can be used to decide the implementation based on user provided string? I have also considered injecting a dictionary of inputs and Service implemntations and inject that in Factory instead of injecting a delegate method but not sure how I can do that in program.cs

Aucun commentaire:

Enregistrer un commentaire