运用Unity实现依赖注入[有参构造注入]

上一篇章讲到关于使用Unity实现依赖注入的简单功能,针对有博友提出关于有参构造注入的问题;

本文同样通过一个实例来讲解如何实现此功能,文中一些分层讲解可以看上一文章(运用Unity实现依赖注入[结合简单三层实例]),本文就不在重复;

1:首先我们在IAopBLL层新建一个IPropertyBLL类,我们增加的两个属性:name跟age

namespace IAopBLL
{
    public interface IPropertyBLL
    {
        string name { set; get; }

        int age { set; get; }

        void ShowInfo();

        void OutShowName();
    }
}

2:逻辑实现接口的代码如下

using IAopDAL;
using IAopBLL;
using Command;
namespace AopBLL
{
    public class PropertyBLL:IPropertyBLL
    {
        IReadData bllServer = new UnityContainerHelp().GetServer<IReadData>();

        public string name { set; get; }

        public int age { get; set; }

        public PropertyBLL(string Name,int Age)
        {
            this.name = Name;
            this.age = Age;
        }

        public void ShowInfo()
        {
            Console.WriteLine(bllServer.ReadDataStr(name));
        }

        public void OutShowName()
        {
            Console.WriteLine("我是从构结函数得到Name的值:{0} 而Age的值:{1}",name,age);
        }
    }
}

*这边有个要注意,因为Unity会自动使用参数最多的构造函数来进行创建对象,假如在这个类中有多个构造函数时,而我们要指定其中一个作为Unity进行创建对象则必需用到[InjectionConstructor],它是在Microsoft.Practices.Unity下面,要对DLL进行引用;比如下面我们使用到一个无参的构造函数让Unity进行创建对象:

using IAopDAL;
using IAopBLL;
using Command;
using Microsoft.Practices.Unity;
namespace AopBLL
{
    public class PropertyBLL:IPropertyBLL
    {
        IReadData bllServer = new UnityContainerHelp().GetServer<IReadData>();

        public string name { set; get; }

        public int age { get; set; }

        public PropertyBLL(string Name,int Age)
        {
            this.name = Name;
            this.age = Age;
        }

        [InjectionConstructor]
        public PropertyBLL()
        {
        }

        public void ShowInfo()
        {
            Console.WriteLine(bllServer.ReadDataStr(name));
        }

        public void OutShowName()
        {
            Console.WriteLine("我是从构结函数得到Name的值:{0} 而Age的值:{1}",name,age);
        }
    }
}

3:接着我们修改公共层里的助手类,增加的方法public T GetServer<T>(Dictionary<string,object> parameterList)其中parameterList是我们用来定义构造函数集合;

using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using Microsoft.Practices.Unity.InterceptionExtension;
using Microsoft.Practices.Unity.InterceptionExtension.Configuration;
using System.Configuration;
using System.Reflection;

namespace Command
{
    public class UnityContainerHelp
    {
        private IUnityContainer container;
        public UnityContainerHelp()
        {
            container = new UnityContainer();
            UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
            container.LoadConfiguration(section, "FirstClass");
        }

        public T GetServer<T>()
        {
            return container.Resolve<T>();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ConfigName">配置文件中指定的文字</param>
        /// <returns></returns>
        public T GetServer<T>(string ConfigName)
        {
            return container.Resolve<T>(ConfigName);
        }

        /// <summary>
        /// 返回构结函数带参数
        /// </summary>
        /// <typeparam name="T">依赖对象</typeparam>
        /// <param name="ConfigName">配置文件中指定的文字(没写会报异常)</param>
        /// <param name="parameterList">参数集合(参数名,参数值)</param>
        /// <returns></returns>
        public T GetServer<T>(Dictionary<string,object> parameterList)
        {
            var list = new ParameterOverrides();
            foreach (KeyValuePair<string, object> item in parameterList) 
            {
                list.Add(item.Key, item.Value);
            }
            return container.Resolve<T>(list);
        }
    }
}

4:配置文章里我们增加一个注册依赖对象的节点

<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>
  </configSections>
  <unity xmlns="http://schemas.microsoft.com/practces/2010/unity">
    <container name="FirstClass">
      <register type="IAopBLL.IReadDataBLL,IAopBLL" mapTo="AopBLL.ReadDataBLL,AopBLL">
      </register>
      <register type="IAopBLL.IPropertyBLL,IAopBLL" mapTo="AopBLL.PropertyBLL,AopBLL"></register>
      <register type="IAopDAL.IReadData,IAopDAL" mapTo="AopOracelDAL.ReadDataDAL,AopOracelDAL"/>
    </container>
  </unity> 
</configuration>

5:接着看一下主程序代码,其中Dictionary<string, object>存储参数的名称跟其对应的值,因为我们的值有可能是不同类型的所以使用object

using IAopBLL;
using Command;
namespace AopUnity
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<string, object> parameterList = new Dictionary<string, object>();
            parameterList.Add("Name", "踏浪帅2");
            parameterList.Add("Age", 27);
            IPropertyBLL bllProperty = new UnityContainerHelp().GetServer<IPropertyBLL>(parameterList);
            Console.WriteLine("--------运行方法ShowInfo()---------");
            bllProperty.ShowInfo();

            Console.WriteLine("--------运行方法OutShowName()---------");
            bllProperty.OutShowName();
            Console.WriteLine("-----------------------------------");
        }
    }
}


6:运行效果:

 

 

如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】按钮。  因为,我的写作热情也离不开您的肯定支持。
 
感谢您的阅读(因为源代码现在我正接着写Unity实现AOP的功能,所以将在实现功能后一起贴出)

posted @ 2013-09-14 16:52  踏浪帅  阅读(5401)  评论(8编辑  收藏  举报