문제

I have a extension method that checks the object for its type and then populate its member property

public static void LoadMeeting<T>(this T entity, IMeetingRepository meetingRepository) 
where T: MyEntity
            {
                var agenda = entity as Agenda;

                if (agenda != null)
                {
                    agenda.Meeting = meetingRepository.GetMeetingById(agenda.MeetingId);
                }

                var participant = entity as Participant;

                if (participant != null)
                {
                    participant.Meeting = meetingRepository.GetMeetingById(participant.MeetingId);
                }

            }

can I further refactor that to something like this to make it more generic?

 public static void LoadMeeting<T>(this T entity, IMeetingRepository meetingRepository) where T : MyEntity
        {
            var obj = entity as Agenda || entity as Participant;

            if (obj != null)
            {
                obj.Meeting = meetingRepository.GetMeetingById(obj.MeetingId);
            }
        }
    }

PS: I don't want to put the object's property Meeting in the Base class (MyEntity)

도움이 되었습니까?

해결책

I would, personally, just use overloads:

public static void LoadMeeting(this Agenda agenda, IMeetingRepository meetingRepository) 
{
    if (agenda != null)
    {
         agenda.Meeting = meetingRepository.GetMeetingById(agenda.MeetingId);
    }
}
public static void LoadMeeting(this Participant participant, IMeetingRepository meetingRepository) 
{
    if (participant != null)
    {
        participant.Meeting = meetingRepository.GetMeetingById(participant.MeetingId);
    }
}

You couldn't do it with a single generic method unless you had some shared contract (either a base class or interface implemented) which provided the Meeting property.

The alternative would be to make a shared interface, ie: IMeeting, then constrain to that:

public interface IMeeting
{
   public Meeting Meeting { get; set; }
   public int MeetingId { get; }
}

Then you can write:

public static void LoadMeeting<T>(this T entity, IMeetingRepository meetingRepository) 

where T: IMeeting { if (entity != null) { entity.Meeting = meetingRepository.GetMeetingById(entity.MeetingId); } }

As you're using EF, you could implement this interface in a partial class:

public partial class Agenda : MyEntity, IMeeting
{
}

다른 팁

You may want to return early out of the method incase you have to handle a class and it's base class.

public static void LoadMeeting<T>(this T entity, IMeetingRepository meetingRepository) where T: MyEntity
        {
            var agenda = entity as Agenda;

            if (agenda != null)
            {
                agenda.Meeting = meetingRepository.GetMeetingById(agenda.MeetingId);
                return;
            }

            var participant = entity as Participant;

            if (participant != null)
            {
                participant.Meeting = meetingRepository.GetMeetingById(participant.MeetingId);
                return;
            }
        }

You might also consider a table approach:

    public static void LoadMeeting<T>(this T entity, IMeetingRepository meetingRepository) where T: MyEntity {
        var name = entity.GetType().Name;
        if (Table.ContainsKey(name)) {
            Table[name](entity, meetingRepository);
            }
        }

Where Table is:

static Dictionary<String, Action<MyEntity, IMeetingRepository>> Table = new Dictionary<String, Action<MyEntity, IMeetingRepository>>();

And it is initialized like so:

        Table.Add("Agenda", (agenda, meetingRepository) => { 
            ((Agenda)agenda).Meeting = meetingRepository.GetMeetingById(((Agenda)agenda).MeetingId); }); 
        Table.Add("Participant", (participant, meetingRepository) => { 
            ((Participant)participant).Meeting = meetingRepository.GetMeetingById(((Participant)participant).MeetingId); }); 

Obviously your Table will have to be static and available to your extension method (say in the containing class).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top