读书人

一个有关问题的设计有关问题关于反射

发布时间: 2013-03-19 17:22:05 作者: rapoo

一个问题的设计问题,关于反射和委托。
有这样一个要求,定时执行某些事件。
比如,有100个事件需要定时执行:
事件1:每周1执行
事件2:每月1号执行
事件3:每天执行
事件4....
这个架构该怎么弄呢?
目前我是这样的:
=========================================================
//一个委托
public delegate void timeChangeHander(DateTime dt);
//=========================================================
//这个是定时执行的类

public class PlanDo
{
private DateTime dt{set;get;}
public PlanDo(DateTime dt)
{
this.dt=dt;
}
public event timeChangeHander timeChangeEvent;
protected virtual void PlanTaskExecute()
{
if (timeChangeEvent != null)
{
timeChangeEvent(DateTime.Now);
}
public void DoTask()
{
PlanTaskExecute();
}
}
//=================================================
//定义一个执行任务的接口
public interface IBaseInter
{
void doTask(DateTime dt);
}
//定义一个某些相似的任务的抽象类
public abstract class absSomeType:IBaseInter
{
public virtual bool isSuitDate(DateTime dt)
{
return false;
}
public virtual void doTask(DateTime dt)
{
if(isSuitDate(dt))
{
Console.WriteLine(“基类执行”);
}
}
}
//接下来就是各个具体的执行类了。。。
//这个每月1号执行
public class ExecuteSomeType1 : absSomeType
{
public override bool isSuitDate(DateTime dt)
{
if (dt.Day== 1)
{
return true;
}
return false;
}
public override void doTask(DateTime dt)
{
base.doTask(dt);
Console.WriteLine(“子类1执行”);
}
}
//这个每周1执行
public class ExecuteSomeType2 : absSomeType
{
public override bool isSuitDate(DateTime dt)
{
if (dt.DayOfWeek == DayOfWeek.Monday)
{
return true;
}
return false;


}
public override void doTask(DateTime dt)
{
base.doTask(dt);
Console.WriteLine(“子类2执行”);
}
}
//下面还有很多个这样的子类。。。。
//====================================================
//然后在Main函数中,我会的,是这样写的:
PlanDo observer = new PlanDo(DateTime.Now);
IList<IBaseInter> listType = new List<IBaseInter>();
//以下添加需要计划任务执行的任务
listType.Add(new ExecuteSomeType1());
listType.Add(new ExecuteSomeType2());
listType.Add(new ExecuteSomeType3());
listType.Add(new ExecuteSomeType4());
listType.Add(new ExecuteSomeType5());
listType.Add(new ExecuteSomeType6());
listType.Add(new ExecuteSomeType7());
//。。。。还要加上很多个这样的语句,太多了,想精简一下。。。
foreach (IBaseInter t in listType)
{
observer.timeChangeEvent += new PlanTask.timeChangeHander(t.doTask);
}
observer.DoTask();
//====================================================================
//这是我目前的做法,但是吧,在主函数中,加入各个具体任务的子类部分的语句太多了,而且每次添加一个任务,都要改这
//儿的代码,所以我想用反射来做:
System.Reflection.Assembly ass = System.Reflection.Assembly.GetExecutingAssembly();
Type[] ts = ass.GetModules()[0].GetTypes();
foreach (Type t in ts)
{
object inters = t.GetInterface("IBaseInter",false);
if (inters!=null)
{
if (t.BaseType != typeof(object))
{
IBaseInter all = t as IBaseInter;//这儿总是得到空值,有错误。。。
if (all != null)
{
ober.timeChangeEvent += all.doTask;
}


}
}
}
ober.DoTask();


这样的话,代码就简洁多了,而且,再想添加一个任务的时候,只要实现了IBaseInter接口,就能自动执行,而不必再更改任何代码,可惜的是,上面注释的部分,总是得到空,如果强制转换的话((IBaseInter)t),就提示:无法将“t”(具有“System.RuntimeType”的实际类型)强制转换为“IBaseInter”,是在是可惜啊,所以在此向各位大侠求助,该怎么做,才能使蓝色字体部分得到的不是空,或者,有什么更好的架构,能使得,再增加任务的时候,不必更改大片的代码呢?

[解决办法]
空洞的东西真正用起来,跟没有它而直接了当地使用基本技术,也没有什么太大区别。

不过回到你的问题,假设我们要反射实例化某个接口的对象,可以这样写

[解决办法]
引用:
引用:
public class ExecuteSomeType2:IBaseInter
return (IBaseInter)objType = Assembly.Load(_path).CreateInstance(namespace+"."+classname);

大哥,这是什么意思?这个return应该放到哪儿呢?

介个是动态实例化类
[解决办法]
??

一个简单的职责链,怎么做这么复杂了
[解决办法]
好好学习 天天想上















[解决办法]
学习了
[解决办法]
膜拜。
[解决办法]
引用:
??

一个简单的职责链,怎么做这么复杂了


哥哥,你也说几句啊。
[解决办法]
都快沉了,让它重新浮出水面
[解决办法]
占位
学习...
[解决办法]
学习,期待!
[解决办法]
给你前一个帖子做了回复,希望有帮助.
[解决办法]
一楼的确很高手
[解决办法]
你可以去如梦的空间给他留言。。估计看到了就会再回来了
[解决办法]
路过。。。来接分。。。。
[解决办法]
占位学习。。。
[解决办法]
占位学习。。。


[解决办法]
学 习
[解决办法]
引用:
引用:
引用:
public class ExecuteSomeType2:IBaseInter
return (IBaseInter)objType = Assembly.Load(_path).CreateInstance(namespace+"."+classname);



大哥,这是什么意思?这个retur……


根据_path加载程序集
CreateInstance方法是根据完全限定名(命名空间.类名,例:System.Object)来创建这个类的实例并返回。这里你既然得到了这个类的Type就没必要去加载程序集了,可以直接这样:
System.Reflection.Assembly ass = System.Reflection.Assembly.GetExecutingAssembly();
Type[] ts = ass.GetModules()[0].GetTypes();
foreach (Type t in ts)
{
object inters = t.GetInterface("IBaseInter",false);
if (inters!=null)
{
if (t.BaseType != typeof(object))
{
IBaseInter all = Activator.CreateInstance(t) as IBaseInter;//这儿总是得到空值,有错误。。。
if (all != null)
{
ober.timeChangeEvent += all.doTask;
}
}
}
}
ober.DoTask();

[解决办法]
学习了

[解决办法]
不懂,学习
[解决办法]

[解决办法]
每天都判断一下是不是有任务要执行,然后触发事件,没什么好说的。

读书人网 >asp.net

热点推荐