簡體   English   中英

如何在 C# 中將類構造函數作為參數傳遞

[英]How to pass a class constructor as parameter in C#

我想為服務創建通用的單元測試類。 我的基類盡可能通用,我想將服務構造函數作為參數從派生類傳遞給我的基類,但我不知道如何在 C# 中執行此操作。

public interface IBaseServiceUnitTest<TEntity> where TEntity : BaseEntity
{
    //...some methods
}

public class BaseServiceUnitTest<TEntity> : IBaseServiceUnitTest<TEntity> where TEntity : BaseEntity
{
    private IBaseService<TEntity> _service;

    public BaseServiceUnitTest(Constructor ctor)
    {
        _service = ctor();
    }

    //...implemented methods from IBaseServiceUnitTest
}

public class CustomEntityServiceUnitTest : BaseServiceUnitTest<CustomEntity>
{
    public CustomEntityServiceUnitTest() 
        : base(Constructor ctor)
}

我認為工廠方法在這里會很好地為您服務。

將您的基礎測試夾具標記為抽象的,並定義一個受保護的抽象方法,其簽名與服務構造函數相同。 然后,在您的基本裝置的設置邏輯中調用該方法。

您將不得不為每個派生測試類實現抽象方法,但我認為這是一個合理的折衷。

請注意,我還從測試類中刪除了接口。 根據您提供的示例代碼,它與現在抽象的基類完全多余。 當然,由於您的示例中不明顯的某些原因,它可能很有用——如果是這樣,您可以保留它。

public class BaseServiceUnitTest<TEntity> where TEntity : BaseEntity
{
    private IBaseService<TEntity> _service;

    public BaseServiceUnitTest(Constructor ctor)
    {
        _service = Create(/* your mocked dependencies here */);
    }

    protected abstract IBaseServce<TEntity> Create(Dependency1 d1, Dependency2 d2);

    //...implemented methods from IBaseServiceUnitTest
}

public class CustomEntityServiceUnitTest : BaseServiceUnitTest<CustomEntity>
{
    // "arg1, arg2"
    protected override IBaseService<CustomEntity> Create(Dependency1 d1, Dependency2 d2) =>
        new BaseService<CustomerEntity>(d1, d2);
}

附錄

如果你真的想讓事情變得自動化,你可以試試這個問題的答案。 它會起作用,但您將犧牲“F12 功能”(使用 Visual Studio 的快捷方式查找和瀏覽引用的能力)和構造函數及其參數的編譯時驗證。 就個人而言,我可能會使用工廠方法。


附錄 #2

為了完整起見,還值得注意的是,如果您的被測服務沒有構造函數參數,您也可以使用new的約束 根據您的意見,在這種情況下聽起來不太行,但下次可能會有用。

暫無
暫無

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

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