前述:今天主要介绍Ioc以及通过Unit如何实现这种机制。

一、IOC概念的引出

我们都知道在设计分层架构,层与层之间应该是松散耦合,这个可以说是老生常谈的概念。“松散耦合”实际是指上层类不能具体依赖于下层类,而应该依赖于下层提供的一个接口。

所以通常做法是在层与层之间通过接口来对接,来解耦,举个简单的例子:

   public interface IIoC

   {

       void ShowIoc();

   }

   public class IoC : IIoC

   {

       public void ShowIoc()

       {

          //实现逻辑

       }

   }

  static void Main(string[] args)

  {

     IIoC ioc = new Ioc();

     ioc.ShowIoc();

  }

  上面的代码看着貌似也行,通过接口来调用,也符合OO原则,但是一定程度上还是相对紧耦合.为了实现解耦,GOF模式也就顺理成章的引出.

  比如非常经典的抽象工厂模式(Abstact Factory).下面直接上代码.

   public class IoCInjector 

   {

      public object GetIoCObject(string className)

      {

          object iocObj;

          string AssemblyName, fullClassName;

          AssemblyName= System.Configuration.ConfigurationManager.AppSettings("AssemblyName"

          //命名空间+类的名称,指明要实例化的类的路径

          fullClassName = AssemblyName+ "." + className 

          //通过反射,取得数据访问层对象

          iocObj = Assembly.Load(AssemblyName).CreateInstance(fullClassName) 

          return iocObj

       }

   }

  <appSettings>

    <add key = "AssemblyName" value = "抽象工厂模式" />

  </appSettings>

   public interface IAbstractFactory

      public IIoC CreateIoc(); 

   } 

   

   public class AbstractFactory : IAbstractFactory {

      IoCInjector iocInjector = new IoCInjector();

      public IIoC CreateIoC(){

            IIoC iioc = iocInjector.GetIoCObject("IoC") as IIoC;  //将实例注入,而不需要去new实例化

            return iioc;

      }

   }

   public class Client

      public static void main(string[] args){ 

        IAbstractFactory abstractFactory = new AbstractFactory (); 

        abstractFactory.CreateIoc().ShowIoc(); 

    } 

} 

看了上面的代码,可以大概了解IOC大概是个什么意思;理论上来说也就是将类之间的关系通过第三方进行注射,不需要类自己去解决调用关系。也就是实现调用者和被调用者解耦.

IOC又称Dependency Injection模式(DI):是依赖注射的意思,也就是将依赖先剥离,然后在适当时候再注射进入。

而通过上面的例子依赖注入的理论基础是Abstract Factory设计模式,那下面就真正引入IoC机制,继续看代码。

  public class UnityDependencyResolver{

     private readonly IUnityContainer _container;

     public UnityDependencyResolver()
        : this(new UnityContainer())
     {

     }

     public UnityDependencyResolver(IUnityContainer container)
     {
        if (container == null)
           throw new ArgumentNullException("container");

        this._container = container;
        //code container
        ConfigureContainer(this._container);
     }

     protected virtual void ConfigureContainer(IUnityContainer container){

        container.RegisterType<IIoC, IoC>();   //(c#) code 方式实现

     }

     protected virtual void ConfigureContainer(IUnityContainer container){  //Config方式实现

        UnityConfigurationSection section = ConfiguratinManager.GetSection("Unity") as UnityConfigurationSection;

        container.LoadConfiguration(section);

     }

     public T Resolve<T>()
     {

        T obj = default(T);
        if (container.IsRegistered<T>())
            obj = container.Resolve<T>();
        else throw new Exception("没有 " + name);
        return obj;
     }

     public T Resolve<T>(string name)
     {

        T obj = default(T);
        if (container.IsRegistered<T>(name))
            obj = container.Resolve<T>(name);
        else throw new Exception("没有 " + name);
        return obj;
     }

  }

   public static class IoCC{

      private static DependencyResolver _resolver;

      public static void InitializeWith(DependencyResolverFactory factory)
      {
          if (factory == null)
              throw new ArgumentNullException("factory");

          _resolver = factory.CreateInstance();
      }

      public static T Resolve<T>()
      {
          return _resolver.Resolve<T>();
      }

      public static T Resolve<T>(string name)
      {
          return _resolver.Resolve<T>(name);
      }

   }

下面是Config的xml配置文件:

    <?xml version="1.0" encoding="utf-8" ?>

     <configuration>

        <configSections>

           <section name="Unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>

        </configSections>

        <Unity xmlns="http://schemas.microsoft.com/practices/2010/unity">

            <alias alias="IIoC" type="Unity.IIoC, Unity" />

            <alias alias="IoC" type="Unity.IoC, Unity" />

           <container>

               <register type="IIoC" name="ConfigIIoC" mapTo="IoC" />

            </container>

        </Unity>

     </configuration>

下面是客户端调用,没啥好说的:

   public class Cliect{

      IIoC iioc = IoCC.Resolve<IoC>(this.GetType().FullName);

      iioc.ShowIoc();

   }

posted on 2013-06-17 14:50  tzj19810812  阅读(413)  评论(0编辑  收藏  举报