zoukankan      html  css  js  c++  java
  • Newlife.XCode对象容器与接口操作实例

            本博客所有文章分类的总目录:http://www.cnblogs.com/asxinyu/p/4288836.html

    Newlife XCode组件相关文章目录:http://www.cnblogs.com/asxinyu/p/4329747.html

    1.前言

    最近一个人狂看X组件的源码,从CommonEntityXCode,然后XCoderXCode。感觉自己有很大的进步,视野更加开放,也能够更加顺手的做很多事情。

    大石头在5月份左右的时候,录制了几期视频教程,其中有一期“使用对象容器来解耦业务模块与管理平台”,对理解X组件很有好处,这期视频我前后已经听了4遍,当然每听一遍都有一些新的发现与体会。今天要总结也是对象容器的一点理解以及为了解决问题,在XCoder源码中发现的一些东西:接口操作。 

    2.XCode对象容器介绍

     XCode对象容器的使用在XCode后台和Newlife.CommonEntity中有大量的使用,这也是后台很容易扩展的原因之一。只需要继承相应的实体类(自动注册优先级高于内部类),而基类中的代码都是通过接口操作,这样继承的类就会优先被系统采用。 管理平台和业务平台通过接口和对象容器联系起来。对象容器注册接口的优先级: 

    1.对象容器注册优先采用配置文件中指定的接口 

    2.配置文件里面没找到之后,会去寻找所有的程序集,找到实现该接口的类,优先级仅次于配置文件。 

    3.内部实现的类优先级要低,12都没找到,就按默认的实现注册顺序采用。 

    对象容器的注册在静态构造函数中,服务容器基类是泛型基类,这样只要是继承基类,然后加一个静态构造函数,就可以在程序中给实现的接口的类进行注册。 

    上面是石头的一些总结,听起来可能不容易理解,下面举一个例子,也算是昨天晚上研究了2个小时的成果吧。 

    3.XCoder接口操作的实例 

    XCoder代码生成器中,可以将数据库模型保存为XML文件,并可以直接加载XML文件进行模型的修改操作。但是其中有一些不便利。我想做一个直接添加模型的界面,这就涉及到一个问题,如何实例化一个IDataTable对象,查看XCoder的源码发现了下面的东西: 

     1 private void btnAddTable_Click(object sender, EventArgs e)
     2         {
     3             if (Tables == null || Tables.Count < 1) return;
     4 
     5             Type type = Tables[0].GetType();
     6             if (type == null) return;
     7 
     8             IDataTable table = TypeX.CreateInstance(type) as IDataTable;
     9             if (table == null) return;
    10 
    11             Tables.Add(table);
    12             table.ID = Tables.Count;
    13             table.TableName = "NewTable" + table.ID;
    14             table.Description = "新建表" + table.ID;
    15 
    16             SetTables(Tables, Tables.Count - 1);
    17         }

     关键的代码是:Type type = Tables[0].GetType();这里直接获取当前数据库中表的类型,然后:

    和 IDataTable table = TypeX.CreateInstance(type) as IDataTable; 这里实体化一个接口,再进行赋值。

    XCoder内部这样做,是有优势的。因为这是导入模型之后才进行的,导入模型的时候,默认实现IDataTable的类已经确定了,因为有对象容器,看XCodeService 

     1  /// <summary>XCode服务对象提供者</summary>
     2     class XCodeService : ServiceContainer<XCodeService>
     3     {
     4         static XCodeService()
     5         {
     6             var container = Container;
     7             container.Register<IDataTable, XTable>()
     8                 .AutoRegister<IDataRowEntityAccessorProvider, DataRowEntityAccessorProvider>()
     9                 .AutoRegister<IEntityPersistence, EntityPersistence>()
    10                 .AutoRegister<IModelResolver, ModelResolver>();
    11 
    12             DbFactory.Reg(container);
    13 
    14             EntityAccessorFactory.Reg(container);
    15         }        
    28         #region 使用
    29         /// <summary>创建模型数据表</summary>    
    30         public static IDataTable CreateTable()
    31         {
    32             return Container.Resolve<IDataTable>();
    33         }
    34     }

      container.Register<IDataTable, XTable>();就是XCodeService在静态构造函数中注册IDataTable的默认实现类XTable,下面的使用方法CreateTable()就是返回一个IDataTable对象,然后在系统的其他地方就可以用XCodeService的这个CreateTable方法创建IDataTable对象了。

    那么为什么最上面的代码中,不这样创建IDataTable对象呢?这里代码太多了,只稍微说一下,因为第一段代码这里已经是导入模型之后了,在导入模型过程中,已经确定了Tables的类型,代码如下:

    1 /// <summary>导入模型</summary>       
    2         public static List<IDataTable> Import(String xml)
    3         {
    4             if (String.IsNullOrEmpty(xml)) return null;
    5 
    6             return ModelHelper.FromXml(xml, CreateTable);
    7         }

    这里的方法是DAL类中的,FromXML方法第二个参数是一个委托,这里传入的CreateTable就是创建默认的IDataTable实例,看看他的代码,很简单,就是内部调用一次XCodeService的方法:

    1  /// <summary>建立数据表对象</summary>
    2         internal static IDataTable CreateTable() { return XCodeService.CreateTable(); }

    到这里应该很清楚了,XCoder中操作对表的操作,都是通过IDataTable,而不设计具体的实现类,比如XTable,在外部程序中,你可以使用自己的Table类,实现IDataTable接口,这样XCode内部会优先采用外部的实现类。

    最后,说一下,这并没有解决我的问题,在这里大家可能会注意到,XCodeService类是私有的,DALCreateTable方法是internal ,这样外部程序集就没办法访问得到。如果我要在外部程序中直接获取一个IDataTable 对象,还的确办不到,除非自己重写一个IDataTable,但这样又太麻烦,既然XCode有这样的功能,不知道大石头为什么不把DALCreateTable设为Public,是不是有什么其他考虑?

  • 相关阅读:
    C++ 三数之和
    C++ 保存读取二进制
    流媒体 Ubuntu部署srs、windows部署nginx
    sql函数(三)MERGE INTO函数
    sql函数(二)LISTAGG()函数(列转行函数)
    sql函数(一)ROW_NUMBER() OVER()--表内分组并排序
    java注释(类、构造函数、方法、代码块、单行、属性注释)
    springBoot注解整理
    @DateTimeFormat与@JsonFormat作用
    DataJPA简述与注解
  • 原文地址:https://www.cnblogs.com/asxinyu/p/2879434.html
Copyright © 2011-2022 走看看