Sunday, March 20, 2011

Is it possible to restate these generic constraints in a cleaner way?

Assume following:

public class MyFunkyTable : DbObject
    // this class will be generated

public class MyFunkyDomainObject : DomainObject
    // this class will be custom-made

public class MyFunkyMapper : Mapper<MyFunkyTable, MyFunkyDomainObject>
    // this will be custom mapping code due to wired abstraction and ... "supercool" db-system

in general we do following:

MappingHelper<MyFunkyTable, MyFunkyMapper, MyFunkyDomainObject>.GetSingle(...);

bu the repeating of the generic constraints is a bit an cumbersome (MyFunkyMapper already specifies the generics..)

Is there any way to do something like:


I've already came up with an idea: usage of extension methods, but this isn't what I want...

From stackoverflow
  • Why don't you just do something like

    var item = mappers.Get<MyFunkyMapper>().GetSingle(...);

    This assumes that Mapper<TTable, TDomain> has a GetSingle<TDomain>(...) method. If this is the case, type inference will figure out the generic argument to GetSingle even if you don't write it.

    BTW, have you considered using AutoMapper for mapping purposes instead of rolling your own?

    Andreas Niedermair : this is not the case ... we want our mappers only to map, not to contain any db-call (neither exclusiv per instance programmed, nor per derivation of the base-class). and: for autoMapper fans (i'm one either) i've added a note saying: this will be custom mapping code due to wired abstraction and ... "supercool" db-system --> atm no chance for autoMapper.. sry
    Jeremy McGee : +1 for AutoMapper
    Mark Seemann : @dittodhole: I'm not sure I understand the problem, then. Would it help if we renamed the GetSingle method to MapSingle?
    Andreas Niedermair : nope - cause MappingHelper does the communication with the DB and uses a FromDB/ToDB-method of the concrete mapper
    Mark Seemann : Notice that my example doesn't use any MappingHelper. The `mappers` variable can be whatever you want it to be. If you want to abstract away the DB communication, you can make it an abstract class or an interface. It's really perpendicular to your question on how to simplify the generics of your API.
    Andreas Niedermair : hm ... well ... after thinking about it for some time, your solution might be perfect if we add following: implement extensionMethods in your `mappers` class and let `Get` return a mapper. then i can use the extensionMethods without being too aware of `using` s
  • I think you can't. The compiler can infer type parameters by looking at the arguments of a function, but that's it. Since you do not pass any parameters, you won't be able to use type inference.

    A shortcut I might suggest is a lesser-used functionality of the "using" keyword. Just add at the top of your file (next to the normal using's) this line:

    using TheMapper = MappingHelper<MyFunkyTable, MyFunkyMapper, MyFunkyDomainObject>;

    And then in code


    This shorthand can come in handy if a file accesses one or few mappers.

    Another idea - instead of MappingHelper, why not add all of those things in the Mapper<T1, T2> class? Then you will be able to use

    Andreas Niedermair : i haven't thought of the alias yet ... but this will cause every file, which uses the mappingHelper, to add such an alias. why i do not want to add the db-communication to the concrete mapper has a simple reason: exchangability and redundancy


Post a Comment