Anyone succeeded at injecting Interfaces into Entity Framework 4 Entities, using T4?

Posted by Ciel on Stack Overflow See other posts from Stack Overflow or by Ciel
Published on 2010-05-12T11:30:34Z Indexed on 2010/05/12 11:34 UTC
Read the original article Hit count: 303

Filed under:

Hello:

POCO sort of leaves me wanting: (how can I say I use DI/IoC, if the Repository is not the only place that is creating the entities?)...hence my desire to lock it down, get rid of the temptation of newing up POCOs or EntityObjects anywhere in the code, and just allowing entity interfaces above the Repository/Factory layer.

For a second there, I nearly thought I had it...was editing EF4's T4 in order to inject in an Interface def. Was going swimmingly, compiled and worked, until I got to the Associations...

I wrapped them with a ICollection, and renamed the underlying original collection with a prefix of Wrapped.

Unfortunately, when run, throws an error: //The Member 'WrappedSubExamples' in the CLR type 'XAct.App.Data.Model.EF4.Example' is not present in the conceptual model type 'XAct.App.Data.Model.Entity.Example'. var examples = context2.CreateObjectSet();

My T4 segment I used was (this may not work, as it's the longest code snippet I've ever posted here...sorry):

#region Generic Property Abstraction
<# if (navProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many) {#>
//XAct.App Generic Wrapper:  
 <#=code.SpaceAfter(NewModifier(navProperty))#><#=Accessibility.ForProperty(navProperty)#> ICollection<I<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>> <#=code.Escape(navProperty)#> 

{ get { if (_X<#=code.Escape(navProperty)#> == null){ _X<#=code.Escape(navProperty)#> = new WrappedCollection,<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>>(this.<#=(navProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)?"Wrapped":""#><#=code.Escape(navProperty)#>); } return _X<#=code.Escape(navProperty)#>; } } private ICollection> _X<#=code.Escape(navProperty)#>; <# } else { #> <#=code.SpaceAfter(NewModifier(navProperty))#><#=Accessibility.ForProperty(navProperty)#> I<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#> <#=code.Escape(navProperty)#> { get { return (I<#=code.Escape(navProperty)#>)this.Wrapped<#=code.Escape(navProperty)#>; } set { this.Wrapped<#=code.Escape(navProperty)#> = value as <#=code.Escape(navProperty)#>; } } <# } #> #endregion

which then wraps the original collection, renamed with the prefix 'Wrapped':

/// <summary>
/// <#=SummaryComment(navProperty)#>
/// </summary><#=LongDescriptionCommentElement(navProperty, region.CurrentIndentLevel)  #>
[XmlIgnoreAttribute()]
[SoapIgnoreAttribute()]
[DataMemberAttribute()]
[EdmRelationshipNavigationPropertyAttribute("<#=navProperty.RelationshipType.NamespaceName#>", "<#=navProperty.RelationshipType.Name#>", "<#=navProperty.ToEndMember.Name#>")]
<#
        if (navProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
        {
#>
<#=code.SpaceAfter(NewModifier(navProperty))#><#=Accessibility.ForProperty(navProperty)#> EntityCollection<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>> Wrapped<#=code.Escape(navProperty)#> 
{
    <#=code.SpaceAfter(Accessibility.ForGetter(navProperty))#>get
    {
        return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>>("<#=navProperty.RelationshipType.FullName#>", "<#=navProperty.ToEndMember.Name#>");
    }
    <#=code.SpaceAfter(Accessibility.ForSetter(navProperty))#>set
    {
        if ((value != null))
        {
            ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>>("<#=navProperty.RelationshipType.FullName#>", "<#=navProperty.ToEndMember.Name#>", value);
        }
    }
}
<#
       }
       else
       {
#>
<#=code.SpaceAfter(NewModifier(navProperty))#><#=Accessibility.ForProperty(navProperty)#> <#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#> Wrapped<#=code.Escape(navProperty)#>
{
    <#=code.SpaceAfter(Accessibility.ForGetter(navProperty))#>get
    {
        return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>>("<#=navProperty.RelationshipType.FullName#>", "<#=navProperty.ToEndMember.Name#>").Value;
    }
    <#=code.SpaceAfter(Accessibility.ForSetter(navProperty))#>set
    {
        ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>>("<#=navProperty.RelationshipType.FullName#>", "<#=navProperty.ToEndMember.Name#>").Value = value;
    }
}
<#
    string refPropertyName = navProperty.Name + "Reference";
    if (entity.Members.Any(m => m.Name == refPropertyName))
    {
       //  6017 is the same error number that EntityClassGenerator uses.
        Errors.Add(new System.CodeDom.Compiler.CompilerError(SourceCsdlPath, -1, -1, "6017", String.Format(CultureInfo.CurrentCulture,
                GetResourceString("Template_ConflictingGeneratedNavPropName"),
                    navProperty.Name, entity.FullName, refPropertyName)));
    }
#>
/// <summary>
/// <#=SummaryComment(navProperty)#>
/// </summary><#=LongDescriptionCommentElement(navProperty, region.CurrentIndentLevel)#>
[BrowsableAttribute(false)]
[DataMemberAttribute()]
<#=Accessibility.ForProperty(navProperty)#> EntityReference<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>> <#=refPropertyName#>
{
    <#=code.SpaceAfter(Accessibility.ForGetter(navProperty))#>get
    {
        return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>>("<#=navProperty.RelationshipType.FullName#>", "<#=navProperty.ToEndMember.Name#>");
    }
    <#=code.SpaceAfter(Accessibility.ForSetter(navProperty))#>set
    {
        if ((value != null))
        {
            ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>>("<#=navProperty.RelationshipType.FullName#>", "<#=navProperty.ToEndMember.Name#>", value);
        }
    }
}
<#
        }

The point is...it bugs out. I've tried various solutions...none worked. Any ideas -- or is this just a wild goose chase, and time to give it up?

© Stack Overflow or respective owner

Related posts about entity-framework-4