Question

I have the following POCO classes

public interface IObject
{
    Guid Uid { get; set; }
}

public class Boo : IObject
{
    public Guid Uid { get; set; }
    public String Name { get; set; }
}

public class Foo : IObject
{
    public Guid Uid { get; set; }
    public String Name { get; set; }
}

I am trying to write a generic method to insert any type of object into the database where the type inherit from IObject. I am using the following method for that (with ServiceStackOrmLite underneath):

public interface IDataAccess
{
    IDbConnection GetConnection();

    Boolean InsertObject<T>(T newObj, IDbConnection connection) where T : IDataObject, new();
}

Trying to insert each object separately works as follow :

public static Boolean AddFoo(this Foo foo)
{
    // DataProvider is initiated using an implementation of IDataAccess
    return DataProvider.InsertObject(foo, DataProvider.GetConnection());
}

Question :

I am trying to use the following method as a valid one for both but it fails. The syntax is wrong but consider it as a pseudo code. How can I acheive that? obj will be a boxed Foo or Boo instance

public static Boolean AddObject(this IObject obj)
{
    Type objectType = obj.GetType();
    return DataProvider.InsertObject(obj as objectType, DataProvider.GetConnection());
}
Was it helpful?

Solution

I'm making the assumption that IObject / IDataObject are the same thing - otherwise it is hard to see how the call would ever work. So, the easiest thing to do is to make the caller supply the T:

public static bool AddObject<T>(this T obj) where T : IObject, new()
{
    return DataProvider.InsertObject<T>(obj, DataProvider.GetConnection());
}

However, this is not always workable (the caller might only know about IObject), in which case you can also get the runtime to worry about it:

public static bool AddObject(this IObject obj)
{
    return DataProvider.InsertObject((dynamic)obj, DataProvider.GetConnection());
}

The only other option is reflection via MakeGenericMethod / Invoke - messy and slow.

Frankly, I would advocate a non-generic API here. Reflection and generics do not make good friends. However, ServiceStack may not give you this luxury, in which case, the dynamic approach is probably your most convenient option here.

OTHER TIPS

You can try with generic AddObject extension

public static bool AddObject<T>(this T obj) where T:IDataObject, new()
{
    return DataProvider.InsertObject(obj,DataProvider.GetConnection());
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top