如何使用简单的注入器在运行时更改依赖关系

How to change the dependency at runtime using simple injector

我是简单注射器的新手。我有依赖于 Force Client 的数据访问层。我已经注册了 ForceClient 依赖项。我想在用户登录应用程序后替换 ForceClient 的默认值。

请告诉我如何在 运行 时更改默认值。

Ioc.ServiceContainer.Register(() => new ForceClient(
    "test",
    "test",
    "test"));

这里是关于要求的完整细节。我在我们的 Xamarin 项目中有 DAL,它使用 Developerforce.Force api 从销售人员中检索数据。我正在使用 MOQ 编写单元测试用例来测试 DAL。

DAL 代码。

public CustomerRepository(IForceClient client)
{
    _client = client;                       
}

public async Task<long> GetTotalContacts()
{
    string totalContactCountQry = "some query"

    var customerCount =  await _client.QueryAsync<ContactsTotal>(totalContactCountQry);
    var firstOrDefault = customerCount.Records.FirstOrDefault();

    return firstOrDefault != null ? firstOrDefault.Total : 0;
}

单元测试用例代码。

[SetUp]
public void Init()
{
    forceClientMock = new Mock<IForceClient>();
    forceClientMock.Setup(x => x.ForceClient(It.IsAny<string>(), 
        It.IsAny<string>(), It.IsAny<string>(), It.IsAny<HttpClient>()))
        .Return(new ForceClient(It.IsAny<string>(), It.IsAny<string>(), 
            It.IsAny<string>(), It.IsAny<HttpClient>()));              
    forceClientMock.Setup(x => x.QueryAsync<ContactsTotal>(It.IsAny<string>()))
        .ReturnsAsync(new QueryResult<ContactsTotal>());
    forceClientMock.Setup(x => x.QueryAsync<ContactsTotal>(It.IsAny<string>()))
        .ReturnsAsync(new QueryResult<ContactsTotal>() { Records=new List<ContactsTotal>() });            
}

[Test]
public void GetTotalContacts()
{              
    ICustomerRepository customerRepostory = new CustomerRepository(forceClientMock.Object);
    Assert.AreEqual(customerRepostory.GetTotalContacts().Result,0);
}

关于应用程序初始化的简单注入器注册表

container.Register<IForceClient>((() => new ForceClient(
    UserState.Current.ApiBaseUrl,
    UserState.Current.AuthToken.AccessToken,
    UserState.Current.ApiVersion)), Lifestyle.Transient);

我在注册过程中创建的 ForceClient 实例正在使用所有默认值 UserState 创建。一旦用户登录到应用程序,就会分配实际值。

我除了 ForceClient 实例在登录后具有更新的值以访问销售人员以检索数据但是程序在下面的 DAL 行给出错误

var customerCount =  await _client.QueryAsync<ContactsTotal>(totalContactCountQry);

原因是 forceClient 仍然包含默认值。我如何确保在登录后创建 FoceClient 实例以使用 UserState

的实际值

您可以使用 Func<T> 来完成您想要的。

而不是 IForceClient 在你的类中,你可以注入一个 Func<IForceClient> :

public CustomerRepository(Func<IForceClient> clientFunc)
{
    _clientFunc = clientFunc;
}

public async Task<long> GetTotalContacts()
{
    string totalContactCountQry = "some query"

    // calling _clientFunc() will provide you a new instance of IForceClient
    var customerCount =  await _clientFunc().QueryAsync<ContactsTotal>(totalContactCountQry);
    var firstOrDefault = customerCount.Records.FirstOrDefault();

    return firstOrDefault != null ? firstOrDefault.Total : 0;
}

简单的注入器注册:

// Your function
Func<IForceClient> fonceClientFunc = () => new ForceClient(
    UserState.Current.ApiBaseUrl,
    UserState.Current.AuthToken.AccessToken,
    UserState.Current.ApiVersion);

// the registration
container.Register<Func<IForceClient>>( () => fonceClientFunc, Lifestyle.Transient);