user1025901
user1025901

Reputation: 1909

How to combine a) MEF and Generics in MEF composition engine?

I have the below program in MEF

Method 1:

public ObjectResult<PartnerListingStatement> GetCommissionListingRecords(string uRL, PortalConstant.DataSourceType DataSourceType)
        {  

            ObjectResult<PartnerListingStatement> lstCommissionPartner = null;

            var dataPlugin = DataPlugins.FirstOrDefault(i => i.Metadata["SQLMetaData"].ToString() == DataSourceType.EnumToString());

            if (dataPlugin != null)
            {
                lstCommissionPartner = dataPlugin.Value.GetCommissionListingRecords(uRL);
            }
            return lstCommissionPartner;
        }

Method B

public ObjectResult<CommissionEarned> GetCommissionPaidToPartners(string uRL, PortalConstant.DataSourceType DataSourceType)
        {
            ObjectResult<CommissionEarned> lstCommissionEarned = null;

            var dataPlugin = DataPlugins.FirstOrDefault(i => i.Metadata["SQLMetaData"].ToString() == DataSourceType.EnumToString());

            if (dataPlugin != null)
            {
                lstCommissionEarned = dataPlugin.Value.GetCommissionPaidToPartners(uRL);
            }
            return lstCommissionEarned;
        }

Using generics or the like can these two be combined. Also the data types are different. N.B.~ This question is different than Generics program to access WCF service from client

Thanks

Upvotes: 0

Views: 238

Answers (1)

Gideon Engelberth
Gideon Engelberth

Reputation: 6155

The first question to ask after asking "Can I combine these methods?" is "What do these methods have in common?" I your case, the answer to that would be something like this:

public ObjectResult<***SomeType***> GetValues(string uRL, PortalConstant.DataSourceType DataSourceType)
{
    ObjectResult<***SomeType***> ret = null;

    var dataPlugin = DataPlugins.FirstOrDefault(i => i.Metadata["SQLMetaData"].ToString() == DataSourceType.EnumToString());

    if (dataPlugin != null)
    {
        ret = dataPlugin.Value.***SomeMethod***(uRL);
    }
    return ret;
}

where ***SomeType*** and ***SomeMethod*** are the two meaningful differences between the methods. The deal with the type, make the method generic and replace all the ***SomeType*** with the generic parameter. To deal with the method, add a delegate parameter to the method. Based on its usage, the delegate will be of the Func<PluginType, string, ObjectResult<***SomeType***>> type where PluginType is whatever type dataPlugin.Value is. Now you have:

public ObjectResult<T> GetValues<T>( //do come up with a better name
    string uRL, 
    PortalConstant.DataSourceType DataSourceType,
    Func<PluginType, string, ObjectResult<T>> resultSelector)
{
    ObjectResult<T> ret = null;

    var dataPlugin = DataPlugins.FirstOrDefault(i => i.Metadata["SQLMetaData"].ToString() == DataSourceType.EnumToString());

    if (dataPlugin != null)
    {
        ret = resultSelector(dataPlugin.Value, uRL);
    }
    return ret;
}

which is changes GetCommissionListingRecords to (the generic type should be inferred)

GetValues(uRL, DataSourceType, (p, u) => p.GetCommissionListingRecords(u));

and similarly for the other method.

Upvotes: 2

Related Questions