重新创建对象和 DI
Posted
技术标签:
【中文标题】重新创建对象和 DI【英文标题】:Recreating an object and DI 【发布时间】:2021-08-29 22:39:49 【问题描述】:我正在编写一个与 API 客户端对象一起使用的类,该对象有时会损坏并且必须从使用它的对象内部重新创建。使用依赖注入的最佳方法是什么?我对从类内部调用 DI 框架犹豫不决,因为它使我的代码依赖于它。
public class MyObject
protected IMyAPIClient Client get; set;
public MyObject(IMyAPIClient client)
Client = client;
protected async Task<ReturnType> Run<ReturnType>(Func<Task<ReturnType>> action, int attempt = 1)
try
return await action();
catch(Exception exception)
Client = await GetNewClient();
if(attempt > MAX_ATTEMPTS)
throw new Exception($"Failed attempt times", exception);
return await Run(action, attempt++);
protected async Task<IMyAPIClient> GetNewClient()
// what to do here?
我想出的一个解决方案是在一个知道 IMyAPIClient 类型的类中实现 IMyAPIClient 并重新创建它,从而绕过 DI 框架。我想知道这是否明智,或者是否有更好的方法?
【问题讨论】:
如果您的 IMyAPIClient 实例不稳定,我会尝试修复它。如果你改写你的问题并添加导致问题的代码,也许这里有人可以找到真正的问题。 BR 您使用的是什么 IoC 框架?例如,如果您使用 Autofac,这很容易 - 只需注入一个 func。 通常最好找出问题的原因而不是更换它。否则我们永远学不会 【参考方案1】:我会首先尝试解决 ApiClient 的问题。对有缺陷的代码使用变通办法很少是一个好主意,但有时可能需要第三方代码。如果问题出在第三方代码中,也可能建议将其放在单独的进程中,否则您无法知道失败是否有一些意想不到的副作用。
要创建新对象,我建议注入某种工厂。具体如何完成将取决于 DI/IoC 框架。最简单的可能是Func<IMyAPIClient>
,但另一种选择是显式工厂类。您可以选择工厂是应该使用 IoC 容器来构造对象,还是直接构造它。此外,一些 IoC 框架会以某种特殊的方式处理工厂,而另一些框架可能需要像其他所有东西一样注册工厂。查看您的框架的文档,了解应如何管理工厂。
如果可能,我还建议将重启逻辑移至装饰器。这样就和使用分离了,在有多个用户或者需要更新逻辑的情况下应该更加灵活。但是,注册装饰器可能有点棘手,以确保它们正常工作,但这也取决于您的 IoC 框架。
【讨论】:
【参考方案2】:我通过创建一个创建 IMyAPIClient 的工厂类解决了这个问题。 这样我就可以在这个工厂类中处理依赖注入,而无需让其他代码依赖于 DI 框架。
public class MyObject
protected IMyAPIClientFactory ClientFactory get; set;
public MyObject(IMyAPIClientFactory clientFactory)
ClientFactory = clientFactory;
Client = clientFactory.CreateClient();
protected async Task<ReturnType> Run<ReturnType>(Func<Task<ReturnType>> action, int attempt = 1)
try
return await action();
catch(Exception exception)
Client = await clientFactory.CreateClient();
if(attempt > MAX_ATTEMPTS)
throw new Exception($"Failed attempt times", exception);
return await Run(action, attempt++);
【讨论】:
以上是关于重新创建对象和 DI的主要内容,如果未能解决你的问题,请参考以下文章