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).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.