簡體   English   中英

如何將對象轉換為Type屬性中定義的類型?

[英]How can I cast an object as a type defined in a Type property?

我的課程看起來像這樣:

public RepositoryManager
{
    public Type Context {get; private set;}

    public RepositoryManager(Type context)
    {
        Context = context;
    }

    public IRepository<T> GetRepository<T>() where T : class
    {
        // create an instance of Context to pass to repo ctor
        var contextInstance = Activator.CreateInstance(Context);  // fail
        return new Repository<T>(contextInstance);
    }
}

我知道我需要將contextInstance作為Context的類型,但我不知道如何做到這一點。 我不能做typeof(Context)因為編譯器抱怨我使用了像'type'這樣的屬性(在這種情況下我的意圖)。

如何將Context屬性中存儲的類型實例傳遞給Repository對象的構造函數?

更新/澄清

基於一些答案,我似乎沒有清楚地解釋自己。

我在Context屬性中存儲的類型很可能是DbContext的實現...例如由實體框架代碼第一次逆向工程創建的SailingDbContext。 它也可以是JudoDbContext。 或者其他一些完全無關的背景。 我不知道它可能是什么。 不過,我知道該類型將提供給大會。

存儲庫中的T將會出現POCO。 也許客戶或產品。 我真的不知道,我也不在乎......我只知道它會存在。

需要為Repository的構造函數傳遞Context屬性中定義的類型的實例。 這是我的問題。 如何將Activator創建的對象強制轉換為Context屬性中定義的類型?

根據請求,我添加了Repository類的構造函數。 但是,我擔心這會使事情進一步混亂。 我沒有看到如何嘗試將Activator創建的對象的對象實例轉換為屬性中定義的類型,這可能會受到實例傳遞給的內容的影響。

public class Repository<T> : IRepository<T>, IDisposable where T : class
{

    private readonly DbSet<T> _dbSet;
    public DbContext Context {get; set;}

    public Repository() 
    {
        // dont use ...
    }

    public Repository(DbContext context)
    {
        Context = context;
        _dbSet = Context.Set<T>();
    }

    // lots more code snipped
 }

請記住,這是IRepository接口的具體實現。 將Activator創建的對象直接轉換為類型DbContext並不是一個好的答案。

同樣,我只是試圖將對象強制轉換為Context屬性中定義的類型。

您需要使用“dynamic”而不是“var”來獲得運行時動態創建的好處。 “var”解析/驗證仍然在編譯時發生。

dynamic contextInstance = Activator.CreateInstance(Context);

您可以在MakeGenericType的幫助下動態創建泛型類型,然后簡單地轉換它:

public class RepositoryManager
{
    public Type Context { get; private set; }

    public RepositoryManager(Type context)
    {
        Context = context;
    }

    public IRepository<T> GetRepository<T>() where T : class
    {
        var contextInstance = Activator.CreateInstance(Context);
        var repositoryType = typeof(Repository<>).MakeGenericType(Context);
        var repository = Activator.CreateInstance(repositoryType, contextInstance);
        return (IRepository<T>)repository;
    }
}

我建議你使用UnitOfWork模式和Repository:

public class SqlRepository<T>: IRepository<T> where T: class, IEntity
{
    protected readonly DbSet<T> _objectSet;

    public SqlRepository(ApplicationDbContext context)
    {
        _objectSet = context.Set<T>();

    }
}

而你UnitOfWork類:

public class SqlUnitOfWork<T> : IUnitOfWork<T> where T : class, IEntity
{
    private ApplicationDbContext _db;
    public SqlUnitOfWork(ApplicationDbContext context)
    {
        _db = context;
    }

    public IRepository<T> Repistory
    {
        get
        {
            return new SqlRepository<T>(_db);
        }
    }

}

在asp.net mvc中有時候你需要在同一個控制器上使用其他類型的存儲庫來進行測試讓我們說你需要在PersonController中查詢帳戶然后在這個模式中你可以輕松地在你的unitOfWork中寫這樣的東西:

    public IRepository<TEntity> GetTypeRepository<TEntity>() where TEntity : class, IEntity
    {
        return new SqlRepository<TEntity>(_db);
    }

這樣,每次需要新的存儲庫時,您都不需要實例化新的上下文。 我順利接口定義了。 希望能幫助到你。 :)

你試試這個嗎?

var contextInstance = Activator.CreateInstance("YourAssemblyFullName", Context.FullName);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM