为了实现动态实例化类的效果,写了个类似如下功能的静态方法 |
|
![]() |
方法就是控制反转:
1. 使用代码注册,用代码向工厂注册对象的键和对象的创建过程,这样有新的东西时工厂不用改,只是多一条注册语句。 2. 使用配置文件注册,工厂使用配置文件的定义,动态创建对象。这样有新的东西时工厂同样不用改,只是多一条配置。 3. IoC/DI框架,主流框架同时支持上面两种方式,工厂也不用写了。 |
![]() |
pre class=”brush: csharp”>
interface IHandler { } class AHandler : IHandler { public void Hello() { MessageBox.Show(“Hello Jimmy”); } } public static IHandler CreateHandler(string ClassName) { IHandler handler = (IHandler) System.Activator.CreateInstance(typeof(ClassName)); eturn handler; } /pre> 调用的时候 pre class=”brush: csharp”>IHandler h = CreateHandler(“xxxx”); AHandler ah = h as AHandler; /pre> /div> |
![]() |
随便给你搜了个网页,可以参考一下:http://www.360doc.com/content/10/1206/14/16915_75504826.shtml
|
![]() 15分 |
或者参考这个更好一些:
a href=”http://blog.csdn.net/st_kalecgos/article/details/20791649″ target=”_blank”>http://blog.csdn.net/st_kalecgos/article/details/20791649 a href=”http://ywjwest.blog.163.com/blog/static/11923417820112131143869/” target=”_blank”>http://ywjwest.blog.163.com/blog/static/11923417820112131143869/ /div> |
![]() |
简单来说,假设需要编写一个工厂方法返回 A子类对象(这个类型是“以后”才扩展的),那么你可以写
public static class MyFactory { public static A CreateInstance() { string cfg= ConfigurationManager.AppSettings["provider_A"].ToString(); string[] cfs = cfg.Split(","); //用逗号前边为类型名称(包含命名空间),逗号后边为Assembly名称 Assembly asm = Assembly.Load(cfs[1]); Type t = asm.GetType(cfs[0]); return (A)System.Activator.CreateInstance(t); } } /pre> |
![]() 15分 |
我给你写个通过代码注册的吧:
pre class=”brush: csharp”> 使用方法如下: // 按照程序集里面类型的MyClassAttribute自动注册 MyFactory.RegisterAssembly(Assembly.GetExecutingAssembly()); // 手动注册 MyFactory.Register(“c”, () => new MyClassC()); // 按key创建对象 var a = MyFactory.Create(“a”); var b = MyFactory.Create(“b”); var c = MyFactory.Create(“c”); // 打印检查下具体类型 Console.WriteLine(a.GetType().Name); Console.WriteLine(b.GetType().Name); Console.WriteLine(c.GetType().Name); 代码: public interface IMyInterface { } [AttributeUsage(AttributeTargets.Class, Inherited = false)] public sealed class MyClassAttribute : Attribute { public string Key { get; private set; } public MyClassAttribute(string key) { Key = key; } } [MyClass(“a”)] public class MyClassA : IMyInterface { } [MyClass(“b”)] public class MyClassB : IMyInterface { } public class MyClassC : IMyInterface { } public class MyFactoryBase<T> { private static Dictionary<string, Func<T>> s_funcs = new Dictionary<string, Func<T>>(); public static void Register(string key, Func<T> createFunc) { s_funcs[key] = createFunc; } public static void RegisterAssembly(Assembly a) { foreach (var type in a.GetTypes().Where(t => t.IsPublic && t.IsClass && !t.IsAbstract && typeof(T).IsAssignableFrom(t))) { var attr = Attribute.GetCustomAttribute(type, typeof(MyClassAttribute)) as MyClassAttribute; if (attr != null) { var t = type; Register(attr.Key, () => (T)Activator.CreateInstance(t)); } } } public static T Create(string key) { return s_funcs[key](); } } public class MyFactory : MyFactoryBase<IMyInterface> { } /pre> 这代码我没写任何检查。关于Activator.CreateInstance,这个东西比较慢,如果要这样创建大量对象,可以用表达式编译优化,这里就不写了。 可以看到,使用时如果有新的类,那么加一个手动注册,或者加个attribute让它自动注册。factory本身是不需要改的。 |
![]() |
泛型方法
public static A create<T>() where T:A 当然ioc是极好的 |
![]() |
可以考虑IOC的方式,用抽象 + 反射实现。 |