C # interface (call method in another project / assembly)

The code below pretty much sums up what I want to achieve.

We have a solution that includes many different projects, however we need to be able to call methods on projects from projects that are not referenced (will cause a circular reference).

I've posted previous questions and the code below is pretty much about using interfaces. I still don't know how I can call a method that is in another project that is not being referenced.

I cannot instantiate the interface, it must be a class. But how can I create an instance of a class that is not referenced. I don't want to use thinking for this.

Code - C # 2.0

Any help is appreciated.

What code do I need to place in the "GeneralMethod" (Class Raise) to be able to execute the "Update" method in the "Listen" class?

// 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");
        }
    }
}

      

I should probably elaborate on the motivation required for this. Perhaps there is a better way ...

We have a basic form that all other projects refer to. As an example, we pass in an object that contains various settings for the project when it is loaded (from the base form).

If, for example, the settings object has some variables (a settings object filled in the baseform), we would like the loaded project to listen for this change and receive a new settings object.

Since the baseform refers to all other projects, we want the projects to listen for events in the baseform.

Remove like dirt :-)

+1


source to share


5 answers


I used Activator.CreateInstance

to do this. You load the assembly from the path and then instantiate the class. For example, you can use this to load gadget builders in a host application where the host is unaware of the gadgets at compile time.

Sample pseudocode (no error handling)

Create an interface for the class you are about to load:

public interface IRemote
{
     void Update();
}

      



Then you need a method to load the assembly and call the function

Now you can use it all:

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

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

      

+2


source


You need a Link project to provide a way to register and build concrete interface implementations. ProjA will then register the implementation and ProjB can query it.

In the mounting link:

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 { ... }
}

      

In the ProjA assembly:

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

      



In the ProjB assembly:

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

      

You then provide some configuration that ensures ProjA registers its implementation before ProjB asks for it.

An easier way is to use the dependency injection framework to manage this stuff for you, or change your projects to layers without circular dependencies.

+1


source


I should probably elaborate on the motivation required for this. Perhaps there is a better way ...

We have a basic form that all other projects refer to. As an example, we pass in an object that contains various settings for the project when it is loaded (from the base form).

If, for example, a settings object has some variables (a settings object filled in baseform), we would like the loaded project to listen for this change and receive a new settings object.

Since the baseform refers to all other projects, we want the projects to listen for events in the baseform.

Clean like dirt. :-)

0


source


Another option is to define a publisher subscriber model. So in your referencing project (a project that referencing all projects) you might have something like this (this is psuedo code, so it won't compile on its own, but will close you:

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. 
   }
}

      

Now you can define your own signature for your delegate so that you can pass any state you want to your own event argument class. When each of them wakes up, they need to register for their events ... you must also enter unregistered.

The nice thing is that you can have any part of your application talking to any other part without having to connect them.

Edited

Here is an article about something similar to what we used. He had a better article but I can't find it: http://www.codeproject.com/KB/cs/eventpool.aspx

Here's a follow-up use of generics in accoutn: http://www.codeproject.com/KB/cs/EventPool_Revisited.aspx

0


source


A simple solution:

Class "Raise" in the project Link to links Link. Thus, it can call methods directly on the objects defined there.

Something in the project reference will be called by the Raise class. Then he needs to raise the event.

The Listen class can listen for this event and respond.

0


source







All Articles