将反射对象转换为反射的通用接口

时间:2013-03-27 16:49:12

标签: generics reflection entity-framework-5 .net-4.5 entityframework.extended

我正在开发一个基于.NET 4.5,EF5和GenericRepository.EntityFramework构建的项目。我正在尝试创建一个发布服务,该服务将对专门用于创作和移动的数据库中的记录采取一些操作

第一个问题是我的类型转换为(IBaseRepository<BaseEntity>)失败。 通过使用直接转换为...来测试第一个存储库(我在下面的示例DataBucket类中列出的存储库)时,我很成功。

object myRepository = p.GetValue(entity, null);  
IBaseRepository<MRClassification> risk = myRepository;

因为myRepository采用'MRClassification'对象类型

问题是每个存储库的签名不同,是否可以返回IBaseRepository<p.PropertyType.GetInterfaces()[0].GenericTypeArguments[0]>的列表,该列表将返回每个存储库作为类型的实体?

我考虑使用协方差,但我在BaseRepository中有方法将T作为参数,如

public virtual new void Add(T entity) { do something; }

出版物应用代码

    public static void DeactivateNonTransversableExpiredRecords()
    {
            IEnumerable<Tuple<IBaseRepository<BaseEntity>, Type>> nonTransversableList =
                GetNonTransversableRepositories(Databucket);

            foreach (var repository in nonTransversableList)
            {
                ////IQueryable recordsToExpire =
                    ////((IBaseRepository<BaseEntity>)repository).FindBy(
                    ////    p => Convert.ToDateTime(p.ExpirationDate).Date <= DateTime.Now.Date && p.IsActive);
                IQueryable recordsToExpire = repository.Item1.FindBy(p => p.IsActive);

                foreach (var row in recordsToExpire)
                {
                    ((BaseEntity)row).IsActive = false;
                    ((IBaseRepository<BaseEntity>)repository).Edit((BaseEntity)row);
                }
            }
        }


        private static IEnumerable<Tuple<IBaseRepository<BaseEntity>, Type>> GetNonTransversableRepositories(object entity)
        {

            PropertyInfo[] properties =
                entity.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);

            List<Tuple<IBaseRepository<BaseEntity>, Type>> list = new List<Tuple<IBaseRepository<BaseEntity>, Type>>();
            foreach (PropertyInfo p in properties)
            {
                if (!typeof(ITransversableRepository).IsAssignableFrom(p.PropertyType))
                {
                    if (OpenGenericIsAssignableFrom(typeof(IBaseRepository<>), p.PropertyType))
                    {
                        list.Add(
                            new Tuple<IBaseRepository<BaseEntity>, Type>(
                                (IBaseRepository<BaseEntity>)Activator.CreateInstance(p.PropertyType),
                                p.GetValue(entity, null)));
                    }
                }
            }
            return list;
        }

DataModel解决方案中的POCO实体和存储库

    --- DataBucket
public class DataBucket : Audit, IDataBucket
{
    private IMRClassificationRepository mrClassCodeRepository;

    public IMRClassificationRepository MRClassificationRepository
    {
        get { return this.mrClassCodeRepository ?? (this.mrClassCodeRepository = new MRClassificationRepository(this.dataContext)); }
    }
    ...
}

--- Repository Class Headers
public class MRClassificationRepository : BaseRepository<MRClassification>, IMRClassificationRepository
{
    ...
}

public interface IMRClassificationRepository : IBaseRepository<MRClassification>
{
    ...
}   

public abstract class BaseRepository<T> : CoreRepository<T>, IBaseRepository<T> where T : BaseEntity, IBaseEntity
{
    ...
}
public interface IBaseRepository<T> : ICoreRepository<T> where T : BaseEntity
{
    ...
}   

--- Entity Class Headers
public class MRClassification : RiskClassification
{
    ...
}
public abstract class RiskClassification : Revisionable
{
    ...
}

public abstract class Revisionable : BaseEntity, IRevisionableEntity
{
    ...
}

public class BaseEntity : IBaseEntity
{
    ...
}

public interface IBaseEntity : IEntity<Guid>
{
    ...
}

0 个答案:

没有答案