在开发WinForm程序,我们往往有很多模块是互相调用的,而由于分工的问题,这些模块又是处于不同的程序集里(有些是系统设计不合理所致),如果直接引用,将会导致程序集的相互引用。
一种做法是可以通过主窗体协调这些模块的工作。但引用的问题是,很多时候主窗体又是另外一个所做,从而增加了模块的耦合,又使主窗体的工作增加;互相调用的模块如都是顶级的窗体等,通过主窗体的协调的的做法还不是很复杂,假如一个模块的第二或第三层的窗体调用另一模块的第二或第三层窗体等,这种的消息需经层层传递,这使一个简单的调用变得很复杂。
其实我们可以把各模块的公用方法、属性和事件提取为接口放到一个公用的模块中。
如:
public interface MyInterface
{
string MyProperty
{
get;
set;
}
int MyMethod();
event EventHandler MyEvent;
}
在相互调用的类中分别实现相关的接口。我们可以在相关的类通过使用静态方法来得到实例:
如需要的是单例模式的:
Instance
private static m_MyClass ;
private Object lockObj = typeof(MyClass);
public static MyInterface GetSigleInstance()
{
lock(lockObj)
{
if (m_MyClass == null) //如果是Form使用 if(m_MyClass == null || MyClass. IsDisposed)
{
m_MyClass = new MyClass(); //MyClass 实现了MyInterface接口
}
}
return m_MyClass;
}
public static MyInterface GetNewInstance()
{
return new MyClass();
}
但是这还不能够实现相互的调用。如果直接使用还是会导致程序集相互引用的问题。我们必需还得使用一个公用的模块来获得模块的实例。假设还是和接口同在一个程序集,我们创建一个类,通过该类的静态方法,使用反射的机制来获取所要的实例。
Create Instance
public abstract InstanceFactory
{
private static BindingFlags bf = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic;
public static T GetInstance<T>(string assemblyName, string classFullName, string invokeMethodName)
{
Assembly assembly = Assembly.Load(assemblyName);
Type instanceType = assembly.GetType(classFullName, true, true);
//创建一个新实例。
//T instance = (T)instanceType.InvokeMember(null, bf | BindingFlags.CreateInstance, null,
null, new object[] { });
//通过静态方法获取实例
T instance = (T)instanceType.InvokeMember(invokeMethodName, bf | BindingFlags.Static |
BindingFlags.InvokeMethod, null, null, null);
return instance;
}
}
在其中一个实例的某方法使用如下调用如下:
Invoke Method
IMyInterface frm = InstanceFactory.GetInstace<IMyInterface>("MyForm","MyForm.FrmMyForm", "GetSingleInstance");
frm.MyProperty = "我是YourForm";
((Form)frm).Show();
frm.MyMethod();
经过这样,我们可以随时随地的进行交互了,各模块的耦合度也降到最低了
该实现经FrameWork2.0 测试通过。
此做法只是一个解决方法,并不代码最好的方法。