menglin2010

一、场景

我们使用手机打电话的时候,因为手机没有电了,所以需要先给手机充上电,我记不住电话号码,所以需要再打开电话本,我习惯戴上耳机打电话,所以最后要戴上耳机打电话。
也就是说在这个场景下:构造手机对象的时候,手机对象依赖于充电器对象,同时依赖电话本对象,同时也依赖于耳机对象

二、接口

1、手机接口

手机接口,里面有两个方法,一个是打电话,一个是戴上耳机打电话

namespace UnityUse.Interface
{
    public interface IPhoneService
    {
        /// <summary>
        /// 打电话
        /// </summary>
        void Call();

        /// <summary>
        /// 带上耳机打电话
        /// </summary>
        /// <param name="iEarphoneService"></param>
        void EarphoneCall(IEarphoneService iEarphoneService);
    }
}

2、电源接口

电源接口,里面有一个充电方法

namespace UnityUse.Interface
{
    public interface IPowerService
    {
        /// <summary>
        /// 充电
        /// </summary>
        void ChargeBattery();
    }
}

3、电话本接口

电话本接口,里面有一个打开电话本方法

namespace UnityUse.Interface
{
    public interface IPhoneBookService
    {
        /// <summary>
        /// 打开电话本
        /// </summary>
        void Open();
    }
}

4、耳机接口
耳机接口,里面有一个戴上耳机方法

namespace UnityUse.Interface
{
    public interface IEarphoneService
    {
        /// <summary>
        /// 戴上耳机
        /// </summary>
        void PutOn();
    }
}

 三、实现

1、手机接口实现

namespace UnityUse.Service
{
    public class ApplePhoneService : IPhoneService
    {
        public IPowerService IPowerService { get; set; }

        /// <summary>
        /// 属性注入电话本服务
        /// </summary>
        [Dependency]
        public IPhoneBookService IPhoneBookService { get; set; }

        /// <summary>
        /// 构造函数注入电源服务
        /// </summary>
        /// <param name="iPowerService"></param>
        public ApplePhoneService(IPowerService iPowerService)
        {
            IPowerService = iPowerService;
        }

        /// <summary>
        /// 打电话
        /// </summary>
        public void Call()
        {
            Console.WriteLine($"*****************普通方式打电话开始*****************");
            IPowerService.ChargeBattery();
            IPhoneBookService.Open();
            Console.WriteLine($"{nameof(ApplePhoneService)}打电话");
            Console.WriteLine($"*****************普通方式打电话结束*****************");
        }

        /// <summary>
        /// 带上耳机打电话
        /// 方法注入耳机服务
        /// </summary>
        /// <param name="earphoneService"></param>
        [InjectionMethod]
        public void EarphoneCall(IEarphoneService iEarphoneService)
        {
            Console.WriteLine($"*****************带上耳机打电话打电话开始*****************");
            IPowerService.ChargeBattery();
            IPhoneBookService.Open();
            iEarphoneService.PutOn();
            Console.WriteLine($"{nameof(ApplePhoneService)}打电话");
            Console.WriteLine($"*****************带上耳机打电话打电话结束*****************");
        }
    }
}

2、电源接口实现

namespace UnityUse.Service
{
    public class ApplePowerService : IPowerService
    {
        /// <summary>
        /// 电源服务构造函数
        /// </summary>
        public ApplePowerService()
        {
            Console.WriteLine($"{nameof(ApplePowerService)}构造");
        }

        /// <summary>
        /// 充电
        /// </summary>
        public void ChargeBattery()
        {
            Console.WriteLine($"{nameof(ApplePowerService)}充电");
        }
    }
}

 3、电话本接口实现

namespace UnityUse.Service
{
    public class PhoneBookService : IPhoneBookService
    {
        /// <summary>
        /// 电话本服务构造函数
        /// </summary>
        public PhoneBookService()
        {
            Console.WriteLine($"{nameof(PhoneBookService)}构造");
        }

        /// <summary>
        /// 打开电话本
        /// </summary>
        public void Open()
        {
            Console.WriteLine($"{nameof(PhoneBookService)}打开电话本");
        }
    }
}

 4、耳机接口实现

namespace UnityUse.Service
{
    public class EarphoneService : IEarphoneService
    {
        /// <summary>
        /// 耳机服务构造函数
        /// </summary>
        public EarphoneService()
        {
            Console.WriteLine($"{nameof(EarphoneService)}构造");
        }

        /// <summary>
        /// 戴上耳机
        /// </summary>
        public void PutOn()
        {
            Console.WriteLine($"{nameof(EarphoneService)}戴上耳机");
        }
    }
}

 四、调用

namespace UnityUse
{
    class Program
    {
        static void Main(string[] args)
        {
            //1、实例化容器
            IUnityContainer container = new UnityContainer();
            //2、注册类型,但凡要用的类型,都需要注册,否则容器怎么工作呢
            container.RegisterType<IPhoneService, ApplePhoneService>();
            container.RegisterType<IPowerService, ApplePowerService>();
            container.RegisterType<IPhoneBookService, PhoneBookService>();
            container.RegisterType<IEarphoneService, EarphoneService>();
            //3、获取实例
            IPhoneService iPhone = container.Resolve<IPhoneService>();
            iPhone.Call();
            Console.ReadLine();
        }
    }
}

 五、效果图

1、在构造ApplePhoneService的时候,先去构造了ApplePowerService,也就是先构造了电源对象。

2、在构造完ApplePhoneService后,又紧跟着构造了PhoneBookService,也就是构造了电话本对象,因为构造顺序是构造函数注入--属性注入--方法注入

3、在构造完PhoneBookService后,最后构造了EarphoneService,我们在调用的时候没有主动去调用EarphoneCall方法,但是因为EarphoneCall标记了InjectionMethod特性,所以会注入方法的依赖对象,也就同时会调用该方法。

 

六、总结

1、注册类型的时候

没有抽象实现不行,没有父子关系不行,但凡要用的类型,都需要注册,否则容器怎么工作呢?

2、为什么要标记特性

因为那么多属性,那么多构造函数,容器怎么知道要构造哪一个呢?所以需要用特性标记一下。

3、构造函数比较特殊

特殊在就算没有标记特性,容器默认构造找参数最多的构造函数,可以不用特性,不用特性意味着可以去掉对容器的依赖

分类:

技术点:

相关文章: