Call custom constructor with Dapper?

asp.net-membership c# dapper reflection

Question

I'm trying to use Dapper to interface with the ASP.NET SQL Membership Provider tables. I wrapped the SqlMembershipProvider class and added an additional method to get me the MembershipUsers given a certain criteria relating to some custom tables I have.

When querying the data with Dapper, it appears that Dapper first instantiates the class with a parameter-less constructor, and then "maps" the returned columns into the properties on the object.

However, the UserName property on the MembershipUser class has a no setter. Judging from around line 1417 in the Dapper SqlMapper.cs, the method GetSettableProps() only gets settable properties.

I tried to do a MultiMap query to invoke the constructor, but the problem with that is the objects passed into the query are already missing the UserName.

I'm guessing I could modify the GetSettableProps() method, but I'm not sure if that will work, or if it will affect my existing code.

Is there anyway for me to invoke the custom constructor that the MembershipUser class has?

Or is there a reasonable change that I could make to Dapper to support my situation?

** UPDATE **

Marc's answer to use the non-generic/dynamic Query() method was correct, but for posterity, this is the method I was referring to inside Dapper:

static List<PropInfo> GetSettableProps(Type t)
{
    return t
          .GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
          .Select(p => new PropInfo
          {
              Name = p.Name,
              Setter = p.DeclaringType == t ? p.GetSetMethod(true) : p.DeclaringType.GetProperty(p.Name).GetSetMethod(true),
              Type = p.PropertyType
          })
          .Where(info => info.Setter != null)
          .ToList();  
}

Accepted Answer

I would use the non-generic Query API here...

 return connection.Query(sql, args).Select(row =>
     new AnyType((string)row.Foo, (int)row.Bar) {
         Other = (float)row.Other }).ToList();

Using this you can use both non-default constructors and property assignments, without any changes, by using "dynamic" as an intermediate step.


Popular Answer

I use this maybe it's help someone

YourList = connection.Query<YourQueryClass>(Query, arg)
              .Select(f => new ClassWithConstructor(f.foo,f.bar))
              .ToList();  



Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why