1

在 MDriven 中,我想在运行时获取建模类的类型鉴别器。我以为我以前做过,但似乎找不到它,也想不通。

我的意思是首先出现在外部 id 字符串中的整数,例如外部 id “72!i64!12345678”中的“72”。

我需要获得基于 C# 类型的鉴别器,即 typeof(MyClass),而没有任何可用的对象实例。这使得无法从外部 id 字符串中提取鉴别器,因为我当时没有这样的字符串可用并且无法创建一个。

我正在使用Eco.Services.Impl.ExternalIdServiceImpl_DbType外部 id 的类型鉴别器与数据库中的类型鉴别器匹配,以防万一。但是如何在运行时查找类型的鉴别器?

4

2 回答 2

1

在找到源代码后,Eco.Services.Impl.ExternalIdServiceImpl_DbType我能够创建此解决方案:

public static string GetClassDiscriminator<T>(this IEcoServiceProvider sp)
{
    IEcoTypeSystem typeSys = sp.GetEcoService<ITypeSystemService>().TypeSystem;
    IClass cls = typeSys.AllClasses.Cast<IClass>().First(c => c.ObjectType == typeof(T));
    if (sp.GetEcoService<IExternalIdService>() is Eco.Services.Impl.ExternalIdServiceImpl_DbType)
    {
        ORMappingDefinition mapping = ((PersistenceMapperDb)DiamondsPMP.Instance.PersistenceMapper).EffectiveRunTimeMappingProvider.Mapping;
        if (mapping == null)
            throw new InvalidOperationException(PersistenceStringRes.MappingProviderNotInitialized);
        ClassDefinition classdef = mapping.Classes[typeSys.AllClasses[0].Name];
        if (classdef.Discriminators.Count == 0)
            throw new InvalidOperationException(PersistenceStringRes.RootclassHasNoDiscriminatorDefined);
        DiscriminatorDef discriminator = classdef.Discriminators.Cast<DiscriminatorDef>().First();
        DiscriminatorValue discvalue = discriminator.DiscriminatorValuesByClassId(cls.InternalIndex);
        if (discvalue == null)
            throw new InvalidOperationException(PersistenceStringRes.ClassHasNoDiscriminatorValueDefined);
        if (discvalue.IsFinal && cls.SubTypes.Count > 0)
            throw new InvalidOperationException(PersistenceStringRes.DiscriminatorIsFinal);
        return discvalue.Value;
    }
    else
        return cls.InternalIndex.ToString();
}

在我的情况下sp.GetEcoService<IExternalIdService>() is Eco.Services.Impl.ExternalIdServiceImpl_DbType是必需的,因为在我的单元测试中我使用PersistenceMapperMemory,它使用索引TypeSystem.AllClasses作为类型鉴别器,这也是返回的值IClass.InternalIndex

我还注意到这IExternalIdService.ObjectForIdSeperateClassInfo()是错误的。它就像Eco.Services.Impl.ExternalIdServiceImpl正在使用一样,返回一个IObjectInstance错误类型(使用类的索引TypeSystem.AllClasses)。

于 2019-12-10T10:11:21.880 回答
0

鉴别器72也是类的TypeService列表中的索引。

IClass umlClass = (IClass)TypeSystem.AllClasses[72];
于 2019-09-15T20:05:33.583 回答