C# 将API包装在接口周围的目的

C# 将API包装在接口周围的目的,c#,.net,C#,.net,我正在开发一个C#web应用程序,它有一个页面(主页),其中有一个小区域来显示一个小工具。有几种小工具实现一个主界面(IMainInterface)和一个可选界面(iOpationalInterface) 在MainPage中,当与gadget类交互时,它使用以下语法: MyAPI api = new MyAPI(); api.SomeMethod(gadgetClassName, param); 在api.SomeMethod(…)中,它执行以下操作: // use reflection

我正在开发一个C#web应用程序,它有一个页面(主页),其中有一个小区域来显示一个小工具。有几种小工具实现一个主界面(IMainInterface)和一个可选界面(iOpationalInterface)

在MainPage中,当与gadget类交互时,它使用以下语法:

MyAPI api = new MyAPI();
api.SomeMethod(gadgetClassName, param);
在api.SomeMethod(…)中,它执行以下操作:

//  use reflection to get an IMainInterface based on gadgetClassName
Type t = Type.GetType(gadgetClassName);

IMainInterface gadget = (IMainInterface)t.InvokeMember(
    gadgetClassName,
    BindingFlags.CreateInstance,
    null,
    null,
    null);
return gadget.SomeMethod(param)
看看这个MyAPI类,它包含一大堆方法,这些方法映射到IMainInterface和IopationalInterface中定义的相应方法

我的问题是,这个MyAPI类真的必要吗?如果MainPage直接访问接口(IMainInterface和iOpationalInterface),不是会减少开销吗

更新:看到一些答案,我意识到我没有明确指出“几种小工具”意味着不同的类(例如CalendarGadget、TaskGadget)


更新2:添加了更多代码示例

是的,从您问题中的描述来看,反射或任何其他间接机制都是不必要的。我不确定这是否回答了你的问题

// in MainPage:
IList<IMainInterface> gadgets = new List<IMainInterface>
{
(IMainInterface)Activator.CreateInstance(Type.GetType("Gadgets.CalendarGadget")),
(IMainInterface)Activator.CreateInstance(Type.GetType("Gadgets.TaskGadget")),
};
//在主页中:
IList gadgets=新列表
{
(IMainInterface)Activator.CreateInstance(Type.GetType(“Gadgets.CalendarGadget”),
(IMainInterface)Activator.CreateInstance(Type.GetType(“Gadgets.TaskGadget”),
};

是的,根据您问题中的描述,我认为反射或任何其他间接机制都是不必要的。我不确定这是否回答了你的问题

// in MainPage:
IList<IMainInterface> gadgets = new List<IMainInterface>
{
(IMainInterface)Activator.CreateInstance(Type.GetType("Gadgets.CalendarGadget")),
(IMainInterface)Activator.CreateInstance(Type.GetType("Gadgets.TaskGadget")),
};
//在主页中:
IList gadgets=新列表
{
(IMainInterface)Activator.CreateInstance(Type.GetType(“Gadgets.CalendarGadget”),
(IMainInterface)Activator.CreateInstance(Type.GetType(“Gadgets.TaskGadget”),
};

似乎是MyApi混合工厂和消费者的作者。在编译时定义接口成员时,我看不到任何间接访问接口成员的理由。

似乎是MyApi mixed factory and consumer的作者。在编译时定义接口成员时,我看不到任何间接访问接口成员的理由。

通常这并不坏。但我想这对你的意图来说是完全过分了。我建议向国际奥委会借点东西

var api = new MyAPI(new GadgetClass());
api.SomeMethod(parameters);
这会让你的生活变得不那么复杂


希望这能有所帮助一般来说这还不错。但我想这对你的意图来说是完全过分了。我建议向国际奥委会借点东西

var api = new MyAPI(new GadgetClass());
api.SomeMethod(parameters);
这会让你的生活变得不那么复杂


希望这有帮助

MyApi类看起来像是在屏蔽您使用反射来创建对象,null检查可选接口是否未被使用,以及可能是一般使用接口的全部事实。没有所有的代码,这只是猜测。正如Dzmitry Huba指出的,混合工厂和包装是一种难闻的气味,你应该尝试重构它

static class GadgetFactory
{
    public static IMainInterface GetGadget(string className)
    {
         (IMainInterface)Activator.CreateInstance(Type.GetType(className))
    }
}
工厂将创建逻辑解耦,但它应该只负责创建

问:myAPI中是否有任何逻辑,或者如果小工具支持该接口,它只是创建然后分派

如果MyApi没有任何逻辑,很难理解为什么它是必要的。也许MyApi的作者当时没有意识到,您可以在需要时转换到另一个接口。我有一种预感,他们试图保护初级开发人员不受接口的影响

// basic use of interfaces
IMainInterface gadget = GadgetFactory.GetGadget("Gadgets.Calendar");
gadget.SomeMethod();

IOptionalInterface optional = gadget as IOptionalInterface;
if( optional != null ) // if optional is null, the interface is not supported
    optional.SomeOptionalMethod();


一个相关的SO问题

MyApi类看起来像是在屏蔽您使用反射来创建对象,null检查可选接口是否未被使用,以及可能是使用一般接口的全部事实。没有所有的代码,这只是猜测。正如Dzmitry Huba指出的,混合工厂和包装是一种难闻的气味,你应该尝试重构它

static class GadgetFactory
{
    public static IMainInterface GetGadget(string className)
    {
         (IMainInterface)Activator.CreateInstance(Type.GetType(className))
    }
}
工厂将创建逻辑解耦,但它应该只负责创建

问:myAPI中是否有任何逻辑,或者如果小工具支持该接口,它只是创建然后分派

如果MyApi没有任何逻辑,很难理解为什么它是必要的。也许MyApi的作者当时没有意识到,您可以在需要时转换到另一个接口。我有一种预感,他们试图保护初级开发人员不受接口的影响

// basic use of interfaces
IMainInterface gadget = GadgetFactory.GetGadget("Gadgets.Calendar");
gadget.SomeMethod();

IOptionalInterface optional = gadget as IOptionalInterface;
if( optional != null ) // if optional is null, the interface is not supported
    optional.SomeOptionalMethod();


一个相关的SO问题

谢谢您的回复,请参阅我的更新以获得一些澄清。我认为问题中没有足够的信息得出这一结论。如果MainPage无法实例化该类,您如何回答帮助?如果是myAPI实例化了这个类,那么实际上,这已经是IOC的一个变体了。完全纯粹的方法是在代码中没有新的内容。所有这些都将使用IOC容器完成。所以上面的代码只是一个小样本。谢谢你的回复,请查看我的更新以获得一些澄清。我认为问题中没有足够的信息来得出这个结论。如果MainPage无法实例化该类,您如何回答帮助?如果是myAPI实例化了这个类,那么实际上,这已经是IOC的一个变体了。完全纯粹的方法是在代码中没有新的内容。所有这些都将使用IOC容器完成。因此,这里发布的代码只是一个小示例。感谢您的回复,请查看我的更新以获得一些澄清。我仍然不明白您真正的要求,但我已更新了我的答案,使其具有多个gadget…嗯,有趣的解决方案,但我如何调用gadget.SomeMethod()何时在运行时确定小工具?我已经更新了答案,以便在运行时根据小工具的程序集限定类名创建小工具的实例。感谢您的回复,请参阅我的更新以获得一些澄清。我仍然不明白您真正的问题,但我已经更新了答案,使其具有多个小工具…嗯,有趣的解决方案,但是,当gadget在运行时被确定时,我如何调用gadget.SomeMethod()?我已经更新了我的答案,以便在运行时从gadget的程序集质量创建一个gadget的实例