C#接口(不同项目/程序集中的调用方法)

时间:2008-12-16 01:54:29

标签: c# interface polymorphism

以下代码几乎总结了我想要实现的目标。

我们有一个包含许多不同项目的解决方案,但是我们需要能够从未引用的项目中调用项目中的方法(会导致循环引用)。

我已经发布了以前的问题,下面的代码几乎就是我使用接口提出的。我仍然不知道如何调用驻留在未引用的其他项目中的方法。

我无法创建接口的实例,它必须是一个类。但是,如何创建未引用的类的实例。我不想为此使用反射。

代码是C#2.0

感谢任何帮助。

我需要在“GeneralMethod”(Class Raise)中放置哪些代码才能在“Listen”类中执行“Update”方法?

// Link Project
namespace Stack.Link
{
    public class Interface
    {
        public interface Update
        {
            void Update();
        }
    }
}

// Project A
// References Link only
namespace Stack.ProjA
{
    public class Raise
    {
        public void GeneralMethod()
        {
            // I want to place code in here to be able to execute 
            // "Update" method in ProjB.
            // Keep in mind that ProjA and ProjB only reference
            // Link Project            
        }
    }
}

// Project B
// References Link only
namespace Stack.ProjB
{
    public class Listen : Stack.Link.Interface.Update
    {
        public void Update()
        {
            // Do something here that is executed from ProjA
            Console.Write("Executed Method in ProjB");
        }
    }
}

我应该澄清需要这样做的动机。也许还有更好的方法......

我们有一个基础形式,从中引用所有其他项目。作为一个例子,我们将一个包含各种设置的对象传递给项目(从基础形式)。

例如,如果设置对象有一些变量更改(设置对象填充在baseform中),我们希望加载的项目监听此更改并获取新的设置对象。

因为基础形式引用了所有其他项目,所以我们需要让项目“监听”基础形式中的事件。

清除泥土: - )

5 个答案:

答案 0 :(得分:2)

我使用Activator.CreateInstance来执行此操作。您从路径加载程序集,然后创建该类的实例。例如,您可以使用此方法在主机应用程序中加载小工具程序集,主机在编译时不知道小工具。

示例伪代码(无错误处理)

为要加载的类创建一个接口:

public interface IRemote
{
     void Update();
}

然后你需要一个方法来加载程序集并调用函数

现在,这是一种使用所有这些的方法:

private void
   DoRemoteUpdate( string assemblyPath, string className )
{ 
   Assembly assembly   = Assembly.Load(assemblyPath); 
   Type     objectType = assembly.GetType(className); 

   remoteAssembly = (IRemote)Activator.CreateInstance(objectType); 
   remoteAssembly.Update(); 
}

答案 1 :(得分:1)

您需要Link项目来提供注册和构建接口的具体实现的方法。然后ProjA将注册一个实现,ProjB可以请求它。

在汇编链接中:

public interface IThing { void Update(); }

public static class ThingRegistry {
  public static void RegisterThing<T>() where T : IThing { ... }

  public static T CreateThing<T>() where T : IThing { ... }
}

在程序集ProjA中:

internal class Thing : IThing { public void Update() { ... } }

在程序集ProjB中:

public class Listen { 
  public void UpdateThing() {
    ThingRegistry.CreateThing<IThing>().Update();
  }
}

然后,您提供某种配置,以确保ProjA在ProjB请求之前注册它的实现。

更简单的方法是使用依赖注入框架为您管理这些内容,或者将项目重新排列为没有循环依赖关系的层。

答案 2 :(得分:0)

我应该澄清需要这样做的动机。也许还有更好的方法......

我们有一个基础形式,从中引用所有其他项目。作为一个例子,我们将一个包含各种设置的对象传递给项目(从基础形式)。

例如,如果设置对象有一些变量更改(设置对象填充在baseform中),我们希望加载的项目监听此更改并获取新的设置对象。

因为基础形式引用了所有其他项目,所以我们需要让项目“监听”基础形式中的事件。

清除泥土。 : - )

答案 3 :(得分:0)

另一种选择是定义发布者订阅者模型。所以在你的链接项目(所有项目引用的项目)中你可以有类似的东西(这是伪代码所以不会自己编译但是让你关闭:

public class EventBroadcaster {
   //use your singleton pattern of choice. This is not what I would reocmmend but its short
   private static EventBroadcaster Instance=new EventBroadcaster;

   public void RegisterForEvent(string key,Delegate del)
   {
    //Store the delegate in a dictionary<string,del>
   //You can also use multicast delegates so if your settings object changes notify all people who need it
    }

   public void FireEvent(string key,EventArgs e)
   {
   //Get the item and execute it. 
   }
}

现在,您可以为您的委托定义自己的签名,这样您就可以在自己的自定义事件args类中传递所需的任何状态。当每个水池醒来时,让他们注册他们的活动......你也应该实现取消注册。

好的一点是,你可以让你的应用程序的任何部分与任何其他部分交谈而不与它们耦合。

被修改

这是一篇关于我们使用过的东西的文章他之前有一篇更好的文章但是我可以找到它:http://www.codeproject.com/KB/cs/eventpool.aspx

以下是将仿制品纳入accoutn:http://www.codeproject.com/KB/cs/EventPool_Revisited.aspx

的后续工作

答案 4 :(得分:0)

简单解决方案:

项目A中的“升级”类引用项目链接。所以它可以直接在那里定义的对象上调用方法。

项目链接中的某些内容将由类Raise调用。然后它需要举起一个活动。

“听”类可以听取该事件并做出反应。