0

I am working on .NET 6.0 application.

I have an Interface IDestinationFileNaming that is implemented by multiple classes. How I Can choose which class to call based on they implementing same interface. Does Iterface where T :Class plays role here?

public interface IDestinationFileNaming
{
    string Generate();
}

ClassA That Implements above interface

public class ClassA : BaseFileNaming, IDestinationFileNaming
{
    
    public ClassA()
        : base() { }
 

    public override string Generate()
    {
        string fileName = string.Empty;

        try
        {
            fileName = BaseName + "AIM_UBW";
        }
        catch (Exception ex)
        { }

        return fileName;
    }

I ClassB That Implements above interface

 public class ClassB : BaseFileNaming, IDestinationFileNaming
{
    public ClassB()
       : base() { }

    public override string Generate()
    {
        string fileName = string.Empty;

        try
        {
            fileName = BaseName + "DDS_UBW";
        }
        catch (Exception ex)
        { }

        return fileName;
    }
}

I have register dependencies in DI Container as

services.AddScoped<IDestinationFileNaming, ClassA>();
services.AddScoped<IDestinationFileNaming, ClassB>();

ClassC

I want to run ClassA here...

public class ClassC{

   private readonly IDestinationFileNaming _destinationFileNaming;
   
   public ClassC(IDestinationFileNaming destinationFileNaming)         
        :base()
    {
        this._destinationFileNaming = destinationFileNaming;
    }

    public void Run(){
       // Hot to call ClassA from using above Interface?
    }
} 
K.Z
  • 5,201
  • 25
  • 104
  • 240
  • Don’t register based on the interface – Daniel A. White Jun 24 '22 at 11:12
  • Does this answer your question? [How to register multiple implementations of the same interface in Asp.Net Core?](https://stackoverflow.com/questions/39174989/how-to-register-multiple-implementations-of-the-same-interface-in-asp-net-core) – Roman Jun 24 '22 at 11:12
  • then how should I register? – K.Z Jun 24 '22 at 11:13
  • You can get a list and choose accordingly. – McNets Jun 24 '22 at 11:13
  • Have a look at [TryAddEnumerable](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.extensions.servicecollectiondescriptorextensions.tryaddenumerable?view=dotnet-plat-ext-6.0), it's explained in [this video](https://youtu.be/iQ8cNI7a6mk?t=367) – McNets Jun 24 '22 at 11:18

1 Answers1

0

I have found two approaches

Approach 1

register dependencies

 services.AddScoped<IDestinationFileNaming, ClassA>();
 services.AddScoped<IDestinationFileNaming, ClassB>();

Class C

   public class ClassC{

   private readonly IEnumerable<IDestinationFileNaming> _destinationFileNaming;
   
   public ClassC(IEnumerable<IDestinationFileNaming> destinationFileNaming)         
        :base()
    {
        this._destinationFileNaming = destinationFileNaming;
    }

    public void Run(){
       
    }

    private dynamic ResolveObject()
        {
            var x = _destinationFileNamings.SingleOrDefault(_ => _.GetType() == typeof(ClassA));

            var y = x.Generate();

            var a = _destinationFileNamings.SingleOrDefault(_ => _.GetType() == typeof(ClassB));

            var b = a.Generate();

            return x;
        }
    } 

Approach 2

interface

public interface IDestinationFileNaming<T> where T : class
{
    string Generate();
}

register in DI

services.AddScoped<IDestinationFileNaming<ClassA>, ClassA>();
services.AddScoped<IDestinationFileNaming<ClassB>, ClassB>();

Class C

 public class ClassC{

 private readonly IDestinationFileNaming<ClassA> _destinationFileNaming;

 public ClassC(IDestinationFileNaming<ClassA> destinationFileNaming)         
     :base()
 {
     this._destinationFileNaming = destinationFileNaming;
 }

 public void Run(){
    x = _destinationFileNaming.Generate();
 }  
} 
dadhi
  • 4,807
  • 19
  • 25
K.Z
  • 5,201
  • 25
  • 104
  • 240