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 Answer 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– Robert Harvey2015年08月03日 20:03:36 +00:00Commented Aug 3, 2015 at 20:03
-
@RobertHarvey Exactly correct.MikeH– MikeH2015年08月03日 20:05:00 +00:00Commented Aug 3, 2015 at 20:05
-
If you had
Person
inherit from anISay
class and provided a new constructor that takes anISay
object as one of its parameters, would that make it injectable without breaking EF?Robert Harvey– Robert Harvey2015年08月03日 20:08:29 +00:00Commented 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– GHP2015年08月03日 20:10:42 +00:00Commented 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.Robert Harvey– Robert Harvey2015年08月03日 20:13:32 +00:00Commented Aug 3, 2015 at 20:13
Explore related questions
See similar questions with these tags.
Say(name, someExternalAssembly.NameSayer)
? Or even better,SomeExternalAssembly.SayName(anyArbitraryObjectWithAName.Name)
that accepts a mere string as input?