`
strong_fee
  • 浏览: 178717 次
  • 性别: 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 Logo

    在Unity游戏开发中,通常在启动应用程序时会播放一段Unity的开场Logo动画,这是Unity引擎的默认设置。这个Logo展示了Unity的技术和品牌,但有时开发者可能希望去除这个Logo以提供更定制化的用户体验或者满足特定的...

    Figma Converter for Unity适用Unity的Figma转换器Unity游戏开发插件unitypackage

    Figma Converter for Unity适用Unity的Figma转换器Unity游戏开发插件资源unitypackage 版本3.1.0 支持Unity版本2021.3.0或更高 一种自动将布局从 Figma 转换为 Unity Canvas 的资源。 描述 有了这个资产,您可以一键...

    unity多人RPG游戏源码uMMORPG 2D 1.3,Unity精品游戏源码,UnityRPG游戏源码

    Unity游戏代码 ,Unity经典游戏源码 , Unity休闲游戏源码, Unity容易上手的游戏源码,Unity小游戏源码,Unity新手练习源码,Unity个人开发源码,Unity优秀项目,Unity商店优秀作品。 unity多人RPG游戏源码uMMORPG 2D 1.3,...

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

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

    最新Unity插件SteamVR Plugin steamvr-2-8-0.unitypackage

    最新Unity插件SteamVR Plugin steamvr_2_8_0.unitypackage最新Unity插件SteamVR Plugin steamvr_2_8_0.unitypackage最新Unity插件SteamVR Plugin steamvr_2_8_0.unitypackage最新Unity插件SteamVR Plugin steamvr_2_...

    城市赛车手unity3dCity Moto Racer,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包 , 新建空项目直接导入到项目里面就可以运行了,无需其他操作,适合二次开发和学习...

    AE2Unity After Effect To Unity Animation

    《AE2Unity:After Effect 到 Unity 的动画迁移技术详解》 在数字内容创作领域,Adobe After Effects(简称AE)和Unity是两个重要的工具。AE主要用于视觉特效、动态图形和动画制作,而Unity则是一个强大的游戏引擎...

    unity五子棋游戏demo源码

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

    unity日期选择插件 DatePicker for UnityUI

    Unity是一款强大的跨平台游戏开发引擎,它被广泛用于创建2D和3D的互动内容,包括游戏、模拟器以及各种可视化应用。"DatePicker for UnityUI" 是一个专门为Unity设计的日期选择组件,它使得在Unity界面中集成日期选择...

    unity解密游戏系统Adventure Creator

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

    Unity2018去除UnityLogo工具

    "Unity2018去除UnityLogo工具"是一个专为Unity2018版本设计的小型应用程序,旨在帮助用户在构建游戏或应用时移除Unity启动时的公司标识(即Unity Logo)。这可能对于那些希望提供更个性化用户体验,或者需要遵守特定...

    Azure Kinect Examples for Unity.unitypackage

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

    Kinect for unity sdk v2.9.unitypackage

    ### Kinect for Unity SDK v2.9.unitypackage #### 知识点一:Kinect SDK 2.0 for Unity **Kinect SDK 2.0 for Unity** 是一个专为Unity游戏引擎设计的插件,它允许开发者在Unity环境中轻松地访问Kinect设备的各项...

    UnityHub 旧版本

    UnityHub是一款由Unity Technologies开发的官方工具,专为管理和安装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武侠角色扮演游戏源码...

    Unity glTF 2.0 Exporter(Unity导出glTF插件)

    Unity glTF 2.0 Exporter 是一个专为Unity开发者设计的插件,它允许用户将Unity场景中的3D模型对象导出为glTF 2.0格式的文件。glTF,全称“Graphics Language Transmission Format”,是一种开放标准的3D模型格式,...

    (Unity源码)二十一点牌类游戏Blackjack Pro - Playmaker 2.1.rar

    Unity插件源码,资源完整,真实可用Unity插件源码,资源完整,真实可用Unity插件源码,资源完整,真实可用Unity插件源码,资源完整,真实可用Unity插件源码,资源完整,真实可用Unity插件源码,资源完整,真实可用...

    UnityHub旧版本Mac2.4版本

    UnityHub是一款由Unity Technologies开发的官方工具,专为管理和安装Unity编辑器的不同版本而设计。在Mac平台上,UnityHub 2.4版本是该软件的一个旧版本,它提供了对Unity开发环境的便捷管理功能,尤其是对于那些...

Global site tag (gtag.js) - Google Analytics