c# - Proper Architecture: Adding Attributes to Domain Model in .NET -
background
i jeffrey palermo's onion architecture model (similar hexagonal architecture) prescribes domain model @ 'center' , concrete implementations of infrastructure, concrete repositories on periphery.
so have domain model:
//https://libphonenumber.codeplex.com/ using libphonenumber; namespace myapplication.domain { public class speaker { public virtual string name {get;set;} public virtual phonenumber phonenumber {get;set;} } }
now need expose domain model other teams:
- the ui team hypothetically wants add several data validation attributes , custom json serialization attributes.
- the infrastructure team hypothetically wants add xml serialization attributes , custom attributes 3rd party database implementation.
- the public api team hypothetically wants add wcf attributes.
i don't want give every team carte blanche add attributes domain model and don't want them adding of "layer specific" dependencies model assembly.
and case made more complicated because i'm using 3rd party 'domain models' in own (in case using google's libphonenumber handle phone number).
ideally, they'd each need create own wrapper class like:
using myapplication.domain; namespace myapplication.ui.domainwrappers { public class uispeaker { private speaker _speaker; public class uispeaker(speaker speaker = null) { _speaker = speaker ?? new speaker(); } [required] public virtual string name { get{ return _speaker.name; } set{ _speaker.name = value; } } [required] public virtual phonenumber phonenumber { get{ return _speaker.phonenumber ; } set{ _speaker.phonenumber = value; } } //conversion operators public static implicit operator uispeaker(speaker s) { return new uispeaker(s); } public static implicit operator speaker(uispeaker s) { return s._speaker; } } }
question
writing , maintaining uispeaker
class pain , boring boilerplate code.
is there either better way add attributes each team wants add without letting them directly edit domain model? or there tooling can generate these wrapper classes (i thinking possibly weaving tool fody or t4 templates, i'm not familiar enough either know if in use case).
research
i looked around stackoverflow , found similar questions, none hit full scope i'm looking for:
avoid using jsonignore attribute in domain model - concluded use .net native attributes on domain model didn't have take dependency on json.net
add attribute assembly's class - discussed using
customreflectioncontext
add attributes existing type. looks cool, unfortunatly, model handed off 3rd party code (orms, ef, json.net, etc) reflection don't think work here.having separate domain model , persistence model in ddd - confirmed each layer should have it's own version of domain model, didn't discuss if there's tooling / strategies make writing / maintaining code easier.
you can use these options simplify job:
- metadata classes
- object object mappers
- code generation
metadata classes
you can create metadata classes , add attributes data annotations , validation attributes metadata classes , relate these metadata classes main domain classes using associatedmetadatatypetypedescriptionprovider
. such metadata classes attribute containers , using type descriptor mechanisms add attributes main classes.
for example, can register metadata class model way, , let infrastructures benefit typedescriptor
see metadata attributes model:
var provider = new associatedmetadatatypetypedescriptionprovider(typeof(model), typeof(modelmetadata)); typedescriptor.addprovider(provider, typeof(model));
object object mappers
you can have view models, business models , domain models in different layers , using decorate them attributes need each layer, using object object mapper automapper
simplify task of mapping classes each other.
automapper object-object mapper. object-object mapping works transforming input object of 1 type output object of different type. makes automapper interesting provides interesting conventions take dirty work out of figuring out how map type type b. long type b follows automapper's established convention, 0 configuration needed map 2 types.
code generation
you can make creating metadata classes or view model classes more easy using code generation tools. example can create wrapper classes using code generation mechanism t4 templates.
in visual studio, t4 text template mixture of text blocks , control logic can generate text file. control logic written fragments of program code in visual c# or visual basic. generated file can text of kind, such web page, or resource file, or program source code in language.
Comments
Post a Comment