2

I'm using EF (Code first) and I'd like to isolate the properties from the methods (many of the methods reference other libraries that I don't want my database project to have to reference).

As an example, say I have this class

public class Person
{
  public string Name { get; set; }
  public void SayName()
  { 
    SomeExternalAssembly.Say(Name)
  }
}

Because SomeExternalAssembly has nothing to do with the database I'd like to move the SayName method to another assembly while maintaining it in a "version" of Person.

In my ideal world (which doesn't work and is probably a bad idea) I'd inherit Person to DerivedPerson then just cast it back to Person when I need to save it to the DB. While I can perform the cast, when I attempt to add it to the DB I get a System.InvalidOperationException: Mapping and meta data information could not be found for EntityType 'DerivedPerson'.

Since that didn't work the next best solution I can come up with is just adding a Person property to my new class:

public class PersonB
{
  public Person Data;
  public void SayName()
  { 
    SomeExternalAssembly.Say(Data.Name)
  }
}

While this would work, I'm looking for something a little cleaner (and ideally less code changes). The next thought I had was to go with inheriting then add a conversion method using reflection.

Does anyone have a better approach?

5
  • 1
    How about Say(name, someExternalAssembly.NameSayer)? Or even better, SomeExternalAssembly.SayName(anyArbitraryObjectWithAName.Name) that accepts a mere string as input? Aug 3, 2015 at 19:57
  • @RobertHarvey While those are great suggestions for the simplistic example I've given, they make less sense in the real program.
    – MikeH
    Aug 3, 2015 at 20:01
  • Your example couples too closely to SomeExternalAssembly. Aug 3, 2015 at 20:02
  • @RobertHarvey Yeah...I'm terrible at making simplified examples...
    – MikeH
    Aug 3, 2015 at 20:07
  • @RobertHarvey Upon looking through my code a bit more, your suggestion isn't as far off as I thought it might be. I thought I had external references littered everywhere, but there are only about a dozen...few enough to refactor.
    – MikeH
    Aug 3, 2015 at 20:23

1 Answer 1

1

If you are 100% sure you want to "bolt on" methods onto these EF table/classes, then just open them up as partial class in a separate file and add the methods needed:

// location -> /EntityPartials/Person.cs

public partial class Person
{
  public void SayName()
  { 
    SomeExternalAssembly.Say(this.Name); 
    // 'this.*' above is optional but could be used to quickly identify EF data-properties.
  }
}

For the record, I would NOT recommend using partials like this that need to talk to external components that require any kind of class state, since you can't really control constructors easily in EF and therefor lose your power to inject dependencies. However, I have a LINQ-2-SQL project that makes lots of use of the pattern above to do various things like string formatting, conditional validation, etc.

5
  • But that doesn't really decouple the dependency on SomeExternalAssembly. Aug 3, 2015 at 20:03
  • @RobertHarvey Exactly correct.
    – MikeH
    Aug 3, 2015 at 20:05
  • If you had Person inherit from an ISay class and provided a new constructor that takes an ISay object as one of its parameters, would that make it injectable without breaking EF? Aug 3, 2015 at 20:08
  • I'm not sure how you'd tell EF to use your DI-based -constructor for that Person entity when it does a general query, but I suppose its possible.
    – GHP
    Aug 3, 2015 at 20:10
  • You wouldn't... You'd have to cast it to the interface to Say the name. As you can see, I haven't fully thought it out. Aug 3, 2015 at 20:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.