1

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

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

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

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

代码是 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,所有其他项目都可以从中引用。作为示例,我们在加载项目时(从基础表单)将包含各种设置的对象传递给项目。

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

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

清如泥:-)

4

5 回答 5

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(); 
}
于 2008-12-16T18:33:54.387 回答
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 请求它之前注册它的实现。

一种更简单的方法是使用依赖注入框架来为你管理这些东西,或者将你的项目重新排列成没有循环依赖的层。

于 2008-12-16T02:07:07.607 回答
0

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

我们有一个baseform,所有其他项目都可以从中引用。作为示例,我们在加载项目时(从基础表单)将包含各种设置的对象传递给项目。

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

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

清如泥。:-)

于 2008-12-16T03:29:17.130 回答
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. 
   }
}

现在你可以为你的委托定义你自己的签名,这样你就可以在你自己的自定义事件参数类中传递你想要的任何状态。当每个听众醒来时,让他们注册他们的事件......您还应该实施取消注册。

好消息是您可以让应用程序的任何部分与任何其他部分进行通信,而无需它们完全耦合。

已编辑

这是一篇与我们使用的类似的文章他之前有一篇更好的文章,但我找不到它:http: //www.codeproject.com/KB/cs/eventpool.aspx

这是将泛型纳入账户的后续行动:http: //www.codeproject.com/KB/cs/EventPool_Revisited.aspx

于 2008-12-16T03:49:05.373 回答
0

简单的解决方案:

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

项目链接中的某些内容将被 Raise 类调用。然后它需要引发一个事件。

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

于 2008-12-16T16:54:34.383 回答