概念

业务唯一标识 BusinessIdentifier

来源于业务,贯穿于系统的始终 (取代 GUID和DBID)

应用于聚合的根

业务标识的结构设计

业务标识本身是值对象 (Value Object)

业务标识的组合

业务标识的实现

设计时,“注入时”与运行时

生命周期

代码

创建
简单标识
    public struct SequenceIdentifier : BusinessIdentifier
    {
        public SequenceIdentifier(int sequence_no):this()
        {
            FullCode = sequence_no.ToString();
        }
    }

组合标识
    public struct CandidateIdentifier : BusinessIdentifier
    {
        public string FullCode { get; private set; }

        public CandidateIdentifier(SceneIdentifier scene_identifier, SequenceIdentifier sequence_identifier)
            :this()
        {
            Scene = scene_identifier;
            Sequence=sequence_identifier;
            FullCode= BusinessIdentifierExtensions.compose(Scene, Sequence);
        }
        public SceneIdentifier Scene { get;private set; }
        public SequenceIdentifier Sequence { get;private set; }
   }

#####FullCode解析器

完整代码
 public class BusinessIdentifierParser<T> : BusinessIdentifierParser
        where T:BusinessIdentifier
    {
      public T parse(string[] codes)
        {

            var code_cursor = 0;
            var args = new List<object>();
            foreach (var arg_type in ComponentTypes)
            {
                if (IsComposited)
                {
                    var arg_parser = (BusinessIdentifierParser) Container.current.get_an(typeof (BusinessIdentifierParser<>).MakeGenericType(arg_type));
                    var codes_count = arg_parser.count_deep_component();
                    var arg = arg_parser.parse(codes.take(code_cursor, codes_count));
                    args.Add(arg);
                    code_cursor +=  codes_count;
                }
                else
                {
                    args.Add(Convert.ChangeType(codes[code_cursor],arg_type));
                    code_cursor++;
                }

            }

            var result = (T) Activator.CreateInstance(typeof (T), args.ToArray());
            return result;
        }
    }    

解析器的关键代码1: 获取组件标识的解析器
var arg_parser = (BusinessIdentifierParser) Container.current.get_an(typeof (BusinessIdentifierParser<>).MakeGenericType(arg_type));
解析器的关键代码2: 简单标识的参数直接转换
args.Add(Convert.ChangeType(codes[code_cursor],arg_type));
解析器的关键代码3: 用反射生成标识对象(结构)
 var result = (T) Activator.CreateInstance(typeof (T), args.ToArray());
持久化
  public abstract class BusinessIdentifierType<T> : IUserType where T : BusinessIdentifier
    {
      public void NullSafeSet(IDbCommand cmd, object obj, int index)
        {   
        var id = (T)obj;
        ((IDataParameter)cmd.Parameters[index]).Value = id.FullCode;

        }
    }
反持久化
  public abstract class BusinessIdentifierType<T> : IUserType where T : BusinessIdentifier
    {
      public object NullSafeGet(IDataReader dr, string[] names, object ower)
        {
            object obj = NHibernateUtil.String.NullSafeGet(dr, names[0]);
            if (obj == null) return null;
            var value = (string)obj;
            var parser =(BusinessIdentifierParser) Container.current.get_an(typeof (BusinessIdentifierParser<>).MakeGenericType(typeof (T)));
            var result = parser.parse(value);
            return result; 
        }
    }

Url中解析
    public class ContextDataServiceImpl : ContextDataService
   {
        public object get_data_by(ContextDataKey key, string value)
        {
            if (key.Equals(Keys.Context.Candidate))
            {
                return Container.get<BusinessIdentifierParser<CandidateIdentifier>>()
                    .parse(value);
            }
            if (key.Equals(Keys.Context.Exam))
            {
                return Container.get<BusinessIdentifierParser<ExamIdentifier>>()
                   .parse(value);

            }
            if (key.Equals(Keys.Context.Scene))
            {
                return Container.get<BusinessIdentifierParser<SceneIdentifier>>()
                 .parse(value);
            }
        }
    }         

使用

BusinessIdentifier定义:


[Composite()]
[CodeName("Exam")]
public struct ExamIdentifier : BusinessIdentifier
{//省略若干实现细节

    [Component]
    public DistrictIdentifier District
    {...}

    [Component]
    public ExamDefIdentifier ExamDef
    {...}

    [Component]
    public Date Date
    {...}
}

[CodeName("District")]
public struct DistrictIdentifier : BusinessIdentifier
{
}

[CodeName("ExamDef")]
public struct ExamDefIdentifier : BusinessIdentifier
{
}

[CodeName("Date")]
public class Date 
{
}

定义BusinessContextKey:

public static BusinessContextDataKey<ExamIdentifier> Exam = Create<ExamIdentifier>();

定义Context

[Context(typeof(ExamIdentifier))]
public class ExamDetailGet : DiscreteWebRequestCommand
{
}

实现原理

  1. Context解析键的时候,会使用CodeName的值来做键,这里摒弃了原来Keys.UPPERCASE的用法
  2. Context中添加键值对的时候,会先添加Composite的值,然后根据Component来解析组件,依次添加所有组件。这是一个递归过程,也就是说如果组件仍然是一个Composite,那么会继续深入解析。

( 本文版权属于© 2015 卓逸天成 | 转载请注明作者和出处:卓逸知识文库 http://kb.skight.com )