`
strong_fee
  • 浏览: 175977 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

Unity

    博客分类:
  • .Net
阅读更多

Reference:

使用Unity解耦你的系统—PART2——了解Unity的使用方法(1)

使用Unity解耦你的系统—PART2——了解Unity的使用方法(2)

使用Unity解耦你的系统—PART2——了解Unity的使用方法(3)

一、初始化UnityContainer

  1.  
    1. 使用API
    2. IUnityContainer container = new UnityContainer()

      // Register 映射。

    3. 使用配置文件
    4. <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=”IClass” type=”UnityStudyConsole.IDemo.IClass, UnityStudyConsole” />  
        <container name=”First”>
          <register type=”IClass” mapTo=”MyClass” />
        </container>
      </unity>

      IUnityContainer container = new UnityContainer();

      // 使用LoadConfiguration默认使用unity section加载unity(无名字)节点。

      container.LoadConfiguration();

      // 获取section,加载有名字的unity配置。

      UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection(“unity”);
      container.LoadConfiguration(section, “First”);

      参考:

      Using Design-Time Configuration

二、注册

  1.  
    1. 使用RegisterType

      container .RegisterType<IStocksTickerView, StocksTickerForm>() .RegisterType<IStockQuoteService, MoneyCentralStockQuoteService>();

      注:使用RegisterType注册的默认生命周期为transient lifetime(每次使用Resolve或者ResolveAll或者属性注入的时候都实例化一个新实例)。

    2. 使用RegisterInstance
    3. // 注册实例,“UI”为实例名。

      RegisterInstance(new TraceSource(“UI”, SourceLevels.All));

      // 注册接口与实例的映射(MySingleton为映射名)

      myContainer.RegisterInstance<IMyObject>(“MySingleton”, MyRealObject);

      // 注册带有生命周期的接口与实例的映射。

      myContainer.RegisterInstance<IMyObject>(“MySingleton”, MyRealObject, new ContainerControlledLifetimeManager());

      注:使用RegisterInstance注册的实例的生命周期为ContainerControlledLifetimeManager;使用该方法无法为实例制定TransientLifetimeManager生命周期,否则会产生异常。

    4. 属性注入(方法与构造函数注入类似)
      1. 【使用标注】在属性前加[Dependency]标注,如:

        [Dependency]
        public ILogger Logger 

        get { return logger; } 
        set { logger = value; } 
        }

        对于实体类,解析的时候可以使用默认的规则解析。对于接口活虚类,需要注册。如:

      2. RegisterType<ILogger, ConsoleLogger>();

        使用带有名字的的属性注入,如:

        [Dependency(“UI”)]
        public ILogger Logger 

        get { return logger; } 
        set { logger = value; } 
        }

        注册带有名字的Logger,如:

        RegisterType<ILogger, TraceSourceLogger>(“UI”);

      3. 【使用API】使用API进行属性注入
      4. 注册不带名字的属性

        RegisterType<IStockQuoteService, MoneyCentralStockQuoteService>( new InjectionProperty(“Logger”))

        注:其中Logger为MoneyCentralStockQuoteService类中的一个类型为ILogger的属性。

        注入带有名字的属性:

        RegisterType<StocksTickerPresenter>( new InjectionProperty(“Logger”, new ResolvedParameter<ILogger>(“UI”)));

        注:其中new InjectionProperty第二参数是指示要解析一个名字为“UI”的ILogger。

        注册多个属性:

        //注册对象关系时初始化对象的属性
            container.RegisterType&lt;IClass, MyClass&gt;(
                new InjectionProperty("Name", "A班"),
                new InjectionProperty("Description", "A班的描述"));
        重载调用:
        //var myClass = container.Resolve&lt;IClass&gt;(new PropertyOverride
        // ("Name", "重载后的A班"),
        //    new PropertyOverride("Description", "重载后的A班的描述"));
            var myClass = container.Resolve&lt;IClass&gt;(new PropertyOverrides()
            {
                {"Name","重载后的A班"},
                {"Description","重载后的A班的描述"}
            }.OnType&lt;MyClass&gt;());
        注意:The PropertyOverride is not limited to a single type, 
        so it will apply to all resolved objects with a Logger property.
        参考:本篇中的构造函数注入
    5. 构造函数注入
      1. 【使用标注】如果一个类有多个构造函数,则需要在使用的构造参数前加标注:

        [InjectionConstructor]

      2. 【使用API】 注入构造函数

        RegisterType<ILogger, TraceSourceLogger>( “UI”, new InjectionConstructor(“UI”))

        注:其中第一个参数“UI”为ILogger, TraceSourceLogger的映射名,第二个参数new InjectionConstructor(“UI”)为构造函数传入一个字符串类型的参数“UI”。如此,TraceSourceLogger将调用一个带有string类型的构造函数。

        使用这个API注入比用“InjectionConstructor”标注的构造函数的优先级别更高。

        如:

      3. container.RegisterType&lt;IClass, YourClass&gt;(
            new InjectionConstructor("my", new MyClass()));
        container.Resolve&lt;IClass&gt;();
        在调用的时候我们想更换原先注册的值,可以通过ParameterOverrideParameterOverrides
        来实现,其中ParameterOverride是针对一个参数,而ParameterOverrides是针对参数列表:
        // 在使用ParameterOverrides进行重载参数时,
        // 可以使用如上面代码的方式进行指定,但是同样需要使用OnType来指定,
        // 不过这个的OnType指定的类型是注册的对象类型。
        container.Resolve&lt;IClass&gt;(new ParameterOverrides()
            {
                {"test","test"},
                {"my",new MyClass()}
            }.OnType&lt;YourClass&gt;());
        // 在使用ParameterOverride方法来重载参数时,如果注册的参数是一个
        // 具体的对象就需要使用OnType这个扩展方法来指定对应的类型,否则会报错。
        container.Resolve&lt;IClass&gt;(new ParameterOverride("test", "test"), 
           new ParameterOverride("my", "new MyClass").OnType&lt;MyClass&gt;());
         
    6. DependencyOverride
    7. Unity还为我们提供了一个DependencyOverride重载,其使用方法和参数重载、属性重载类似,这边就不演示了,不过需要注意的是DependencyOverride是针对所注册对象类型中所包含的对象类型重载,例如在A类中有构造函数参数是B类,同时也有个属性依赖于B类,当使用了DependencyOverride后,这个A对象原先注册的有关B类的依赖将全部改变。

    8. 注册泛型
      1. 使用API
      2. container .RegisterType( typeof(IRepository<>), typeof(ValidatingRepository<>), “validating”);
        注意:open generic types cannot be used as generic type arguments。

        可以在开闭泛型之间建立映射,也可以在闭映射和非泛型之间建立映射,如:

        RegisterType<IValidator<StockQuote>, RandomStockQuoteValidator>();

        使用overrides解析泛型:

        StocksTickerPresenter presenter = container.Resolve<StocksTickerPresenter>( new ParameterOverride( “repository”, new ResolvedParameter<IRepository<StockQuote>>(“validating”)) .OnType<StocksTickerPresenter>());

      3. 使用配置文件
      4. 闭泛型

        <register type=”IRepository[StockQuote]” mapTo=”DebugRepository[StockQuote]“/>

        开泛型

        <register type=”IRepository[]” mapTo=”DebugRepository[]“/>

        例:

        <register type=”IRepository[]” mapTo=”DebugRepository[]“/>

        public StocksTickerPresenter( IStocksTickerView view, IStockQuoteService stockQuoteService, IRepository<StockQuote> repository) { … }

        IRepository<StockQuote>程:首先查找是否有相应的闭泛型,如果有,则进一步解析构造函数,…;如果没有,则查找开泛型,IRepository<>被找到,此时,开泛型DebugRepository<>被使用,StockQuote被传作泛型参数,解析完毕。

    9. 数组注入
    10. CompositeLogger的构造函数为:

      public CompositeLogger(ILogger[] loggers)
              {
                  this.loggers = (IEnumerable<ILogger>)loggers.Clone();
              }

      注册方法为:

      RegisterType<ILogger, CompositeLogger>( “composite”, new InjectionConstructor( new ResolvedArrayParameter<ILogger>( typeof(ILogger), new ResolvedParameter<ILogger>(“UI”))));

      其中:第一个参数typeof(ILogger是new ResolvedParameter<ILogger>())的简写。

      注意:当解析Array时,只有有名字的实例会被包含进来。

  1.  

三、解析

  1.  
    1. 语法
    2. StocksTickerPresenter presenter = container.Resolve<StocksTickerPresenter>();

      注:如果StocksTickerPresenter的构造函数有参数,则需要先注册参数。

    3. 延迟获取对象
    4. public static void DeferringResolve()
      {
          var resolver = container.Resolve&lt;Func&lt;IClass&gt;&gt;();
      
          //注册IClass与MyClass之间的关系
          container.RegisterType&lt;IClass, MyClass&gt;();
          //获取MyClass实例
          var myClass = resolver();
      
          var resolver2 = container.Resolve&lt;Func&lt;IEnumerable&lt;IClass&gt;&gt;&gt;();
      
          //注册与IClass相关的对象。
          container.RegisterType&lt;IClass, MyClass&gt;("my");
          container.RegisterType&lt;IClass, YourClass&gt;("your");
          //获取与IClass关联的所有命名实例
          var classList = resolver2();
      }
  1.  
    1. 检索容器中注册信息
    2. public static void DisplayContainerRegistrations(
      IUnityContainer theContainer)
      {
          string regName, regType, mapTo, lifetime;
          Console.WriteLine("容器中 {0} 个注册信息:",
                  theContainer.Registrations.Count());
          foreach (ContainerRegistration item in theContainer.Registrations)
          {
              regType = item.RegisteredType.Name;
              mapTo = item.MappedToType.Name;
              regName = item.Name ?? "[默认]";
              lifetime = item.LifetimeManagerType.Name;
              if (mapTo != regType)
              {
                  mapTo = " -&gt; " + mapTo;
              }
              else
              {
                  mapTo = string.Empty;
              }
              lifetime = lifetime.Substring(0, lifetime.Length - 
                     "生命周期管理器".Length);
              Console.WriteLine("+ {0}{1}  '{2}'  {3}", regType, mapTo, 
                    regName, lifetime);
          }
      }

四、生命周期

  1.  
    1. 使用生命周期
      1. 使用API
      2. RegisterType<ILogger, TraceSourceLogger>( “UI”, new ContainerControlledLifetimeManager(), new InjectionConstructor(“UI”))

      3. 使用配置文件
      4. &lt;register type="IClass" mapTo="MyClass"&gt;
          &lt;lifetime type="transient" /&gt;
          &lt;!--&lt;lifetime type="SessionLifetimeManager"
              value="Session#1" typeConverter="SessionLifetimeConverter" /&gt;
          --&gt;
        &lt;/register&gt;<br>

         

    2. 生命周期的类型
      1. ContainerControlledLifetimeManager:维护一个对象实例的强引用,每次调用的时候都会返回同一对象。

      2. ExternallyControlledLifetimeManager:作用类似于singleton,但是当实例没有被引用的时候,垃圾回收期将回收这个实例。 如果被GC回收后再次调用Resolve方法将会重新创建新的对象。调用GC的代码如下:
      3. GC.Collect();

        配置文件如下:

        <register type=”IClass” mapTo=”MyClass” name=”ccl”>
        <lifetime type=”external” />
        </register>

      4. PerThreadLifetimeManager:每个线程拥有一个实例。对于一个线程来说,作用类似于singleton。 一般来说不建议在使用RegisterInstance对已存在的对象注册关系时使用PerThreadLifetimeManager,因为此时的对象已经在一个线程内创建了,如果再使用这个生命周期管理器,将无法保证其正确调用。
      5. <register type=”IClass” mapTo=”MyClass” name=”ccl”>
        <lifetime type=”perthread” />
        </register>

      6. TransientLifetimeManager:每次调用Resolve or ResolveAll或者属性注入的时候都实例化一个新实例时创建新实例。
      7. <register type=”IClass” mapTo=”MyClass” name=”ccl”>
        <lifetime type=”transient” />
        </register>

      8. HierarchicalLifetimeManager:类似于ContainerControlledLifetimeManager,不同之处在于父容器和子容器维护各自的生命周期。也就是说,用子容器注册一个映射之后,用父容器和子容器解析解析出来的实例是不同的。Unity这种分级容器的好处就在于我们可以对于有不同生命周期的对象放在不同的容器中,如果一个子容器被释放,不会影响到其它子容器中的对象,但是如果根节点处父容器释放后,所有的子容器都将被释放。
        <register type="IClass" mapTo="MyClass" name="hl">
              <lifetime type="hierarchical">
        </register>
         
      9. PerResolveLifetimeManager:类似于TransientLifetimeManager,区别在于在第一调用的时候会创建一个新的对象,而再次通过循环引用访问到的时候就会返回先前创建的对象实例。如:
public class View : IView
{
    [Dependency]
    public IPresenter Presenter { get; set; }
}
public class MockPresenter : IPresenter
{
    [Dependency]
    public IView View { get; set; }
}
解析IView得到的实例Presenter 中的View与第一次解析IView的实例为同一个。
 

分享到:
评论

相关推荐

    Unity精品农场经营游戏源码unity完整项目

    Unity游戏代码 ,Unity经典游戏源码 , Unity休闲游戏源码, Unity容易上手的游戏源码,Unity小游戏源码,Unity新手练习源码,Unity个人开发源码,Unity优秀项目,Unity商店优秀作品。 Unity精品农场经营游戏源码unity完整...

    Unity跑酷游戏源码,Utimate 3.0 unity3d精品资源 Infinite Runner Utimate

    Unity跑酷游戏源码,Utimate 3.0 unity3d精品资源 Infinite Runner UtimateUnity精品小游戏源码 , Unity完整项目源码 是Unitypackage包 , 新建空项目直接导入到项目里面就可以运行了,无需其他操作,适合二次开发和学习...

    城市赛车手unity3dCity Moto Racer,Unity竞速赛车游戏源码

    Unity游戏代码 ,Unity经典游戏源码 , Unity休闲游戏源码, Unity容易上手的游戏源码,Unity小游戏源码,Unity新手练习源码,Unity个人开发源码,Unity优秀项目,Unity商店优秀作品。 如果运行或测试时遇到问题,可随时联系...

    unity解密游戏系统Adventure Creator

    unity解密游戏系统Adventure Creator Unity商店的精品资源 适合二次开发和学习使用 是个Unitypackage包 , 创建个空项目直接导入就行了 如果打开报错请切换编译器版本或者下载最新编译器就行了 unity解密游戏系统...

    Azure Kinect Examples for Unity.unitypackage

    Azure Kinect Examples for Unity.unitypackage unity 商城kinect Azure DK的unity例程 这是一组 Azure Kinect(又名 ‘Kinect for Azure’,K4A)示例,其中采用了几个主要脚本,已分组放在一个文件夹中。该资源包...

    unity娘模型下载(优妮蒂/unity_chan)

    游戏引擎研发商Unity Technologies日本分公司Unity Technologie Japan日前宣布,自2014年4月7日起开放官方代言原创角色“优妮蒂(ユニティちゃん)”的高品质3D模型供Unity开发者免费下载与使用。 优妮蒂是日本Unity...

    Unity3d 卡通华丽战斗slash刀光特效VFX

    Unity、3D、特效、刀光、卡通、RPG、VFX、战斗、战斗光影、Unity3D、动作特效、Unity3D、Unity3D、Unity3D、Unity3D、Unity3D、Unity3D、Unity3D、Unity3D、Unity3D、Unity3D、Unity3D、Unity3D、Unity3D、Unity3D、...

    unity武侠游戏源码

    unity武侠角色扮演游戏源码unity武侠角色扮演游戏源码unity武侠角色扮演游戏源码unity武侠角色扮演游戏源码unity武侠角色扮演游戏源码unity武侠角色扮演游戏源码unity武侠角色扮演游戏源码unity武侠角色扮演游戏源码...

    unity5 FPS射击游戏FPSE源码0.95f

    unity5 FPS射击游戏FPSE源码0.95f ...Unity游戏代码 ,Unity经典游戏源码 , Unity休闲游戏源码, Unity容易上手的游戏源码,Unity小游戏源码,Unity新手练习源码,Unity个人开发源码,Unity优秀项目,Unity商店优秀作品。

    unity手势识别系统源码Gesture Recognizer

    unity手势识别系统源码Gesture Recognizer Unity游戏源码 , Unity工具 , 完整的项目 , 适合学习和二次开发 。 是整个完整的UnityPackage包 , 使用新版本编译器请自行升级编译器设置就行 , C#语言的! C#语言的!! C#...

    unity自定义虚拟键盘UI Keyboard(UnityPackage)

    UI Keyboard - Unity Package 这是一个可下载的 Unity 包,可以轻松地集成到您的项目中。它的想法是可以使用基于UI的键盘让用户输入数据。最初,这是由于WebGL在移动设备上的局限性,它不会在输入字段处于活动状态时...

    unity3d打开外置摄像头

    在unity3d里可以打开usb连接的外置摄像头在unity3d里可以打开usb连接的外置摄像头在unity3d里可以打开usb连接的外置摄像头在unity3d里可以打开usb连接的外置摄像头在unity3d里可以打开usb连接的外置摄像头在unity3d...

    Unity国外仿神庙逃亡游戏源码,完整游戏项目

    Unity国外仿神庙逃亡游戏源码,完整游戏项目 , 仿神庙逃亡 , 精品项目Unity精品小游戏源码 , Unity完整项目源码 是完整的项目 , 无需其他操作,适合二次开发和学习使用,经典游戏,需要其他游戏源码包可以看我主页直接...

    unity3D空战游戏《鹰击长空》源码-3DAirPlane

    unity3D空战游戏《鹰击长空》源码-3...Unity游戏代码 ,Unity经典游戏源码 , Unity休闲游戏源码, Unity容易上手的游戏源码,Unity小游戏源码,Unity新手练习源码,Unity个人开发源码,Unity优秀项目,Unity商店优秀作品。

    Unity精品游戏源码, AR生存射击游戏 完整源码

    Unity精品小游戏源码 , Unity完整项目源码 是Unitypackage包 , 新建空项目直接导入到项目里面就可以运行了,无需其他操作,适合二次开发和学习使用,都是经典游戏,需要其他游戏源码包可以看我主页 直接可以运行 , 如果...

    10种Unity粒子特效包资源

    Unity3d特效粒子 光束效果 FXlight pack 特效包 Unity3d特效粒子 火焰刀光特效包 Strike Effects 1.0 Unity3d特效粒子 角色扮演类特效技能 RPG-FPS Fx Pack 特效包 Unity3d特效粒子 蓝色闪电特效包 Electro ...

    unity5超酷3D战斗机空战游戏完整源码

    unity5超酷3D战斗机空战游戏完整源码,...Unity游戏代码 ,Unity经典游戏源码 , Unity休闲游戏源码, Unity容易上手的游戏源码,Unity小游戏源码,Unity新手练习源码,Unity个人开发源码,Unity优秀项目,Unity商店优秀作品。

    unity实现安卓开机自启

    unity打包安卓实现开机自启。本项目源码需要androidStudio4.1打开, unity使用方法:解压后把"androidAutoStar\app\build\outputs\aar\app-debug.aar"文件导入到unity项目中, 打包成功后安装到手机运行后重启手机,...

    Unity经典战斗类卡牌源码Kings - Card Swiping Decision Game Asset

    Unity游戏代码 ,Unity经典游戏源码 , Unity休闲游戏源码, Unity容易上手的游戏源码,Unity小游戏源码,Unity新手练习源码,Unity个人开发源码,Unity优秀项目,Unity商店优秀作品。 如果运行或测试时遇到问题,可随时联系...

    Unity3d 拳皇类大型3D格斗游戏源码 街机对战游戏项目

    Unity3d 拳皇类大型3D格斗游戏源码 街机对战游戏项目 整个项目的完整压缩包 , 直接打开就行 , 无需其他操作 适合二次开发和学习使用 , 如果有问题请切换编译器 或者下载最新编译器 Unity街机游戏源码 Unity3d 拳皇...

Global site tag (gtag.js) - Google Analytics