典型工厂化实现
工厂接口定义
/// <summary> /// 工厂接口定义 /// </summary> /// <remarks> /// TTarget : abstract product type /// TSource: concrete product type /// </remarks> public interface IFactory { #region config and register type mapping /// <summary> /// 如果需要同时加载配置文件中定义的映射关系,可以按照SRP的原则定义独立的配置类型。 /// 由该配置类型调用这两个接口为Factory加载配置信息 /// </summary> IFactory RegisterType<TTarget, TSource>(); // fluent interface IFactory RegisterType<TTarget, TSource>(string name); // fluent interface #endregion #region factory method TTarget Create<TTarget>(); TTarget Create<TTarget>(string name); #endregion }
注册类
public sealed class TypeRegistry { readonly string DefaultNmae = Guid.NewGuid().ToString(); IDictionary<Type, IDictionary<string, Type>> registry = new Dictionary<Type, IDictionary<string, Type>>(); public void RegisterType(Type targetType,Type sourceType) { RegisterType(targetType, sourceType, DefaultNmae); } public void RegisterType(Type targetType, Type sourceType,string name) { if (targetType == null) throw new ArgumentNullException("targetType"); if (sourceType == null) throw new ArgumentNullException("sourceType"); if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name"); IDictionary<string, Type> subDictionary; if (!registry.TryGetValue(targetType, out subDictionary)) { subDictionary = new Dictionary<string, Type>(); subDictionary.Add(name, sourceType); registry.Add(targetType, subDictionary); } else { if (subDictionary.ContainsKey(name)) throw new DuplicateKeyException(name); subDictionary.Add(name, sourceType); } } public Type this[Type targetType, string name] { get { if (targetType == null) throw new ArgumentNullException("targetType"); if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name"); if (registry.Count() == 0) return null; return (registry .Where(x => x.Key == targetType)).FirstOrDefault().Value .Where(x => string.Equals(name, x.Key)) .FirstOrDefault().Value; } } public Type this[Type targetType] { get { return this[targetType, DefaultNmae]; } } }
工厂类
public class Factory : IFactory { protected TypeRegistry registry = new TypeRegistry(); #region IFactory Members public IFactory RegisterType<TTarget, TSource>() { registry.RegisterType(typeof(TTarget), typeof(TSource)); return this; } public IFactory RegisterType<TTarget, TSource>(string name) { registry.RegisterType(typeof(TTarget), typeof(TSource), name); return this; } public TTarget Create<TTarget>() { return (TTarget)Activator.CreateInstance(registry[typeof(TTarget)]); } public TTarget Create<TTarget>(string name) { return (TTarget)Activator.CreateInstance(registry[typeof(TTarget), name]); } #endregion }
调用
[TestMethod] public void CreateInstance() { var factory = new Factory() .RegisterType<IFruit, Apple>() .RegisterType<IFruit, Orange>("o") .RegisterType<IVehicle, Bicycle>() .RegisterType<IVehicle, Bicycle>("a") .RegisterType<IVehicle, Train>("b") .RegisterType<IVehicle, Car>("c"); Assert.IsInstanceOfType(factory.Create<IFruit>(), typeof(Apple)); Assert.IsInstanceOfType(factory.Create<IFruit>("o"), typeof (Orange)); Assert.IsInstanceOfType(factory.Create<IVehicle>(), typeof(Bicycle)); Assert.IsInstanceOfType(factory.Create<IVehicle>("a"), typeof(Bicycle)); Assert.IsInstanceOfType(factory.Create<IVehicle>("b"), typeof(Train)); Assert.IsInstanceOfType(factory.Create<IVehicle>("c"), typeof(Car)); }
其实精髓还是在于注册类的一个类似assembly的功能,通过字典的方式,封装,然后通过泛型来比对实现,或者通过配置文件传参数过来实现出一个新的实例化
里面注意连贯接口,泛型,等操作
posted on 2013-03-28 14:25 HOT SUMMER 阅读(278) 评论(0) 编辑 收藏 举报