首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态调用类

动态调用类
EN

Stack Overflow用户
提问于 2018-10-06 02:21:13
回答 5查看 63关注 0票数 0

假设我有来自两个提供者的两个相同的服务,并且我想编写一段代码,根据客户端请求调用它们中的任何一个。

更清楚地说,我有提供者A和提供者B。客户端将提交对A或B的请求,因此我必须调用它们的类来处理请求。

我创建了provider接口

代码语言:javascript
复制
interface IProviderInterface
{
    string GetRedirectUrl();
    string GetStatus();
}

然后,每个提供程序类都实现了该接口

代码语言:javascript
复制
public class ProviderA: IProviderInterface
{
    public ProviderA()
    {
    }

    public string GetRedirectUrl()
    {
        return "URL for provider A";
    }

    public string GetStatus()
    {
        return "Check status with provider A API";
    }
}

现在,在提供程序管理器类中,我使用switch语句来调用所需的提供程序类。

代码语言:javascript
复制
public class ProvidersManager
{
    IProviderInterface ProviderObj;

    public ProvidersManager(string ProviderName)
    {
        switch (ProviderName)
        {
            case "A":
                ProviderObj = new ProviderA();
                break;
            case "B":
                ProviderObj = new ProviderB();
                break;
        }
    }

    public string GetRedirectUrl()
    {
        return  ProviderObj.GetRedirectUrl();
    }

    public string GetStatus()
    {
        return ProviderObj.GetStatus();
    }
}

但此方法要求我在每次添加新的提供程序时编辑提供程序管理器类。

我想知道是否有一种方法可以在不更改代码的情况下以更动态的方式调用所需的类。

EN

回答 5

Stack Overflow用户

发布于 2018-10-06 02:27:26

使用DI避免在ProvidersManager中进行更改。

或者,您可以重构此代码并创建一个工厂,该工厂负责为所提供的提供者名称提供provider类型的对象。

票数 0
EN

Stack Overflow用户

发布于 2018-10-06 02:31:21

您可以使用一些替代方案来完成此操作:

泛型类型

代码语言:javascript
复制
public class ProvidersManager<TProvider> where TProvider : IProviderInterface
{
    public ProvidersManager() =>
       ProviderObj = Activator.CreateInstance<TProvider>();
}

// eg: new ProvidersManager<ProviderA>();

使用type (在其他地方加载之前)

代码语言:javascript
复制
public ProvidersManager(Type providerImplementationType) =>
    ProviderObj = (IProviderInterface)Activator.CreateInstance(myType);

// eg: new ProvidersManager(typeof(ProviderA));

使用类型全名

代码语言:javascript
复制
public ProvidersManager(string providerFullName) =>
    ProviderObj = (IProviderInterface)Activator.CreateInstance(Type.Load(providerFullName));

// eg: new ProvidersManager("MyApplication.Common.ProviderA");
票数 0
EN

Stack Overflow用户

发布于 2018-10-06 02:32:12

ProviderManager.cs

代码语言:javascript
复制
internal static class ProviderManager
{
    private static readonly Dictionary<string, BaseProvider> _providers = new Dictionary<string, BaseProvider>();

    public static void Register(string name, BaseProvider provider) => _providers.Add(name, provider);
    public static string GetRedirectUrl(string name) => _providers[name].GetRedirectUrl();
    public static string GetStatus(string name) => _providers[name].GetStatus();
}

BaseProvider.cs

代码语言:javascript
复制
internal abstract class BaseProvider
{
    private BaseProvider(string name) => ProviderManager.Register(name, this);  
    public abstract string GetRedirectUrl();
    public abstract string GetStatus();
}

ProviderA.cs

代码语言:javascript
复制
internal class ProviderA : BaseProvider
{
    private readonly string _redirectUrl;
    private readonly string _status;

    public ProviderA(string redirectUrl, string status) : base("A")
    {
        _redirectUrl = redirectUrl
        _status = status;
    }

    public string GetRedirectUrl() => _redirectUrl;
    public string GetStatus() => _status;
}

使用

代码语言:javascript
复制
internal class Program
{
    public static void Main(string[] args)
    {
        ProviderA providerA = new ProviderA("http://stackoverflow.com", "active");
        string url = ProviderManager.GetRedirectUrl("A");
    }
}

希望这能有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52671285

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档