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?

  • 1
    How about Say(name, someExternalAssembly.NameSayer)? Or even better, SomeExternalAssembly.SayName(anyArbitraryObjectWithAName.Name) that accepts a mere string as input? – Robert Harvey Aug 3 '15 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 '15 at 20:01
  • Your example couples too closely to SomeExternalAssembly. – Robert Harvey Aug 3 '15 at 20:02
  • @RobertHarvey Yeah...I'm terrible at making simplified examples... – MikeH Aug 3 '15 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 '15 at 20:23
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.

  • But that doesn't really decouple the dependency on SomeExternalAssembly. – Robert Harvey Aug 3 '15 at 20:03
  • @RobertHarvey Exactly correct. – MikeH Aug 3 '15 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? – Robert Harvey Aug 3 '15 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. – Graham Aug 3 '15 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. – Robert Harvey Aug 3 '15 at 20:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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