栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用DI和IoC的工厂方法

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用DI和IoC的工厂方法

在工厂内部有一个switch case语句是一种代码味道。有趣的是,您似乎根本没有专注于解决该问题。

针对这种情况的最佳,最直接的DI解决方案是策略模式。它允许您的DI容器将依赖项注入到它们所属的工厂实例中,而不会使具有这些依赖项的其他类变得混乱,也不必诉诸服务定位器。

介面

public interface ICarFactory{    ICar CreateCar();    bool AppliesTo(Type type);}public interface ICarStrategy{    ICar CreateCar(Type type);}

工厂工厂

public class Car1Factory : ICarFactory{    private readonly IDep1 dep1;    private readonly IDep2 dep2;    private readonly IDep3 dep3;    public Car1Factory(IDep1 dep1, IDep2 dep2, IDep3 dep3)    {        if (dep1 == null) throw new ArgumentNullException("dep1");        if (dep2 == null) throw new ArgumentNullException("dep2");        if (dep3 == null) throw new ArgumentNullException("dep3");        this.dep1 = dep1;        this.dep2 = dep2;        this.dep3 = dep3;    }    public ICar CreateCar()    {        return new Car1(this.dep1, this.dep2, this.dep3);    }    public bool AppliesTo(Type type)    {        return typeof(Car1).Equals(type);    }}public class Car2Factory : ICarFactory{    private readonly IDep4 dep4;    private readonly IDep5 dep5;    private readonly IDep6 dep6;    public Car1Factory(IDep4 dep4, IDep5 dep5, IDep6 dep6)    {        if (dep4 == null) throw new ArgumentNullException("dep4");        if (dep5 == null) throw new ArgumentNullException("dep5");        if (dep6 == null) throw new ArgumentNullException("dep6");        this.dep4 = dep4;        this.dep5 = dep5;        this.dep6 = dep6;    }    public ICar CreateCar()    {        return new Car2(this.dep4, this.dep5, this.dep6);    }    public bool AppliesTo(Type type)    {        return typeof(Car2).Equals(type);    }}

战略

public class CarStrategy : ICarStrategy{    private readonly ICarFactory[] carFactories;    public CarStrategy(ICarFactory[] carFactories)    {        if (carFactories == null) throw new ArgumentNullException("carFactories");        this.carFactories = carFactories;    }    public ICar CreateCar(Type type)    {        var carFactory = this.carFactories .FirstOrDefault(factory => factory.AppliesTo(type));        if (carFactory == null)        { throw new Exception("type not registered");        }        return carFactory.CreateCar();    }}

用法

// I am showing this in pre, but you would normally // do this with your DI container in your composition // root, and the instance would be created by injecting // it somewhere.var strategy = new CarStrategy(new ICarFactory[] {    new Car1Factory(dep1, dep2, dep3),    new Car2Factory(dep4, dep5, dep6)    });// And then once it is injected, you would simply do this.// Note that you could use a magic string or some other // data type as the parameter if you prefer.var car1 = strategy.CreateCar(typeof(Car1));var car2 = strategy.CreateCar(typeof(Car2));

请注意,由于没有switch
case语句,因此可以在不更改设计的情况下将其他工厂添加到策略中,并且这些工厂中的每个工厂都可以具有自己的依赖性,这些依赖性由DI容器注入。

var strategy = new CarStrategy(new ICarFactory[] {    new Car1Factory(dep1, dep2, dep3),    new Car2Factory(dep4, dep5, dep6),    new Car3Factory(dep7, dep8, dep9)    });var car1 = strategy.CreateCar(typeof(Car1));var car2 = strategy.CreateCar(typeof(Car2));var car3 = strategy.CreateCar(typeof(Car3));


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/411975.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号