如何获得 class 的类型鉴别器?
How to get type discriminator for class?
在 MDriven 中,我想在运行时获取建模 class 的类型鉴别器。我以为我以前做过,但是好像找不到,想不通。
我的意思是在外部 id 字符串中最先出现的整数,例如外部 ID“72!i64!12345678”中的“72”。
我需要获得基于 C# 类型的鉴别器,即 typeof(MyClass),但没有任何可用的对象实例。这使得无法从外部 id 字符串中提取鉴别器,因为我当时没有可用的字符串并且无法创建一个。
我正在使用 Eco.Services.Impl.ExternalIdServiceImpl_DbType
,因此外部 ID 的类型鉴别器与数据库中的类型鉴别器相匹配,以防万一。但是如何在运行时查找类型的鉴别器?
判别器72也是类的TypeService列表中的索引。
IClass umlClass = (IClass)TypeSystem.AllClasses[72];
找到 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
中的 class' 索引)。
在 MDriven 中,我想在运行时获取建模 class 的类型鉴别器。我以为我以前做过,但是好像找不到,想不通。
我的意思是在外部 id 字符串中最先出现的整数,例如外部 ID“72!i64!12345678”中的“72”。
我需要获得基于 C# 类型的鉴别器,即 typeof(MyClass),但没有任何可用的对象实例。这使得无法从外部 id 字符串中提取鉴别器,因为我当时没有可用的字符串并且无法创建一个。
我正在使用 Eco.Services.Impl.ExternalIdServiceImpl_DbType
,因此外部 ID 的类型鉴别器与数据库中的类型鉴别器相匹配,以防万一。但是如何在运行时查找类型的鉴别器?
判别器72也是类的TypeService列表中的索引。
IClass umlClass = (IClass)TypeSystem.AllClasses[72];
找到 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
中的 class' 索引)。