簡體   English   中英

為什么我應該在構造函數中使用接口類型的對象而不是實際類對象

[英]Why should I use Interface type of object in Constructor instead of Actual Class Object

我已將我的企業級項目外包給自由職業者,我也得到了很好的設置。 但是現在合同已經完成,而且這個人也轉向了新技術,換言之,不願意延長合同。 現在我正在研究這個代碼。 我在C#和MVC方面有2年的背景經驗。 下面是我的應用程序架構的粗略概念。 希望我盡力抽象出企業級應用程序的架構細節。 如果您需要進一步了解任何問題,請與我們聯系。


我的所有實體都被定義為C#POCO類:

public class Product : BaseEntity
{
   public int ProductId { get; set; }
   public string ProductName { get; set; }
}

現在我有一個像以下一樣的IDbContext:

public interface IDbContext : IDisposable
{
    IDbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity;      
}

Base Entity是每個POCO實體繼承的Partial POCO類。 這是一個實現此IDBContext的類:

public class MyObjectContext : DbContext, IDbContext
{
    public new IDbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity
    {
        return base.Set<TEntity>();
    }
}

現在我已經定義了一個IDbContextFactory,它負責提供DBContexts:

public interface IDbContextFactory
{
    Lazy<IDbContext> CreateDbContext();
}

實現此IDBContextFactory接口的類具有以下結構:

public class MyDbContextFactory : IDbContextFactory
{
    public MyDbContextFactory(string dbConnectionString)
    {
        _dbConnectionString = Settings.DbConnectionString;
        _dbContext = CreateDbContext();
    }

    public IDbContext CreateDbContext()
    {
        IDbContext dbContext = new IDbContext(() => CreateNewContext());
        return dbContext;
    }

    private MyObjectContext CreateNewContext()
    {
        return new MyObjectContext (_dbConnectionString);
    }
}

在這里,IRepo Pattern發揮作用:

public partial interface IRepository<T> where T : BaseEntity
{
    T GetById(object id);
}

現在,實現此接口的Repository類如下所示:

public partial class EfRepository<T> : IRepository<T> where T : BaseEntity
{
    private readonly Lazy<IDbContext> _dbContext;
    private readonly IDbContextFactory _dbContextFactory;
    private readonly Lazy<ObjectStateManager> _objectStateManager;

    public EfRepository(IDbContextFactory dbContextFactory)
    {
        _dbContextFactory = dbContextFactory;
        _dbContext= _dbContextFactory.CreateDbContext();
        _objectStateManager= new Lazy<ObjectStateManager>(() => ((IObjectContextAdapter)_dbContext.Value).ObjectContext.ObjectStateManager);
    }

    public T GetById(object id)
    {
        return this.Entities.Find(id);
    }
}

到目前為止,我們已完成數據庫訪問管理的基礎架構級別設置。 現在的問題是將此設置用於控制器(因為我直接從控制器訪問存儲庫)如下所示:

public class CountryController: BaseController
{
    private readonly Lazy<IRepository<Country>> _countryRepository;

    public CountryController(Lazy<IRepository<Country>> countryRepository)
    {
        _countryRepository = countryRepository;
    }

    public Country GetCountryById(int id)
    {
        Country country = _countryRepository.Value.GetById(id);

        if (country != null)
            return country;
        else
            return null;
    }

希望以上都清楚。 現在這里有一些我需要回答的問題:

1)為什么我們這樣的分層流程如下:

IDBContext -> IDBContextFactory -> IRepository <T>

然后最終將此IRepository用於控制器以訪問Data對象。 換句話說,為什么我們在為Country Controller實現Constructor Injection時依賴於Interfaces而不是實際的Class Objects?

2)這是企業級應用程序的正確方法,因為它應該具有很大的可擴展性以用於將來的目的。 如果還有其他的話我會很高興知道嗎?

3)在Controller的構造函數中我使用了Lazy>,那么這個懶惰的目的是什么呢?它實際上是否有益如果是,那么以什么方式?

這是設計模式。 它被稱為依賴注入

EfRepository類要求使用其構造函數注入其依賴項 - 這稱為構造函數注入 我們還可以允許依賴項通過公共屬性注入,稱為setter注入

MVC模式最重要的特征之一是它能夠分離關注點。 我們希望應用程序中的組件盡可能獨立,並且盡可能減少相互依賴性。

在我們理想的情況下,每個組件對任何其他組件一無所知,只通過抽象接口處理應用程序的其他區域。 這稱為松耦合 ,它使我們的應用程序的測試和修改更容易。 接口可以幫助我們解耦組件。

我們需要的是一種獲取實現給定接口的對象而無需直接創建實現對象的方法。 該問題的解決方案稱為依賴注入 (DI),也稱為控制反轉 (IoC)。

DI是一種設計模式,它通過添加接口來完成我們開始的松散耦合。

行情從第3章復制本書。

暫無
暫無

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

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