Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Autofac:注册异步工厂方法_C#_Asynchronous_Dependency Injection_Autofac_Factory Method - Fatal编程技术网

C# Autofac:注册异步工厂方法

C# Autofac:注册异步工厂方法,c#,asynchronous,dependency-injection,autofac,factory-method,C#,Asynchronous,Dependency Injection,Autofac,Factory Method,TL;DR:Autofac是否支持类似AutoFixture的fixture.Get()机制 我正在使用Autofac,需要调用异步工厂方法,如下所示: class AppModel { public static async Task<AppModel> CreateAsync(IDependency x, IDependency2 y) { ... } } 我在infrastructure components领域,靠近合成根目录,可能会以编程方式定义组件注

TL;DR:Autofac是否支持类似AutoFixture的
fixture.Get()
机制

我正在使用Autofac,需要调用异步工厂方法,如下所示:

class AppModel
{
     public static async Task<AppModel> CreateAsync(IDependency x, IDependency2 y)
     { ... }
}
我在infrastructure components领域,靠近合成根目录,可能会以编程方式定义组件注册和/或执行其他应该限制在那里的不好的操作。我不介意涉及反射,因为它只被调用一次

重要的是,我确实需要观察
任务
产生的任何
异常

任务
在很大程度上是一个转移视线的任务,但问题是,按照定义同步工厂方法并让Autofac完成这项任务的正常模式,这项任务将不会执行(至少不会直接执行),也就是说,我不能将其更改为:

     public static AppModel CreateAsync(IDependency x, IDependency2 y)
     { ... }
<>太长了,读不下去了。我也不想让两个阶段初始化——我不需要对象在初始化之前可用。 您可以实现
ResolveAsync
方法系列:-

public static Task<T> ResolveAsync<T1, T>(Func<T1, Task<T>> func)
{
    return func(_container.Resolve<T1>());
}

public static Task<T> ResolveAsync<T1, T2, T>(Func<T1, T2, Task<T>> func)
{
    return func(_container.Resolve<T1>(), _container.Resolve<T2>());
}

public static Task<T> ResolveAsync<T1, T2, T3, T>(Func<T1, T2, T3, Task<T>> func)
{
    return func(_container.Resolve<T1>(), _container.Resolve<T2>(), _container.Resolve<T3>());
}
var appModel = await container.ResolveAsync<IDependency,IDependency2>(AppModel.CreateAsync);
公共静态任务解析异步(Func-Func)
{
return func(_container.Resolve());
}
公共静态任务ResolveAsync(Func-Func)
{
返回func(_container.Resolve(),_container.Resolve());
}
公共静态任务ResolveAsync(Func-Func)
{
返回func(_container.Resolve(),_container.Resolve(),_container.Resolve());
}
这使我能够做到:

var appModel = await ResolveAsync<IDependency,IDependency2>(AppModel.CreateAsync);
var-appModel=await-ResolveAsync(appModel.CreateAsync);
或者很明显,这些可以转化为扩展方法:-

public static Task<T> ResolveAsync<T1, T>(Func<T1, Task<T>> func)
{
    return func(_container.Resolve<T1>());
}

public static Task<T> ResolveAsync<T1, T2, T>(Func<T1, T2, Task<T>> func)
{
    return func(_container.Resolve<T1>(), _container.Resolve<T2>());
}

public static Task<T> ResolveAsync<T1, T2, T3, T>(Func<T1, T2, T3, Task<T>> func)
{
    return func(_container.Resolve<T1>(), _container.Resolve<T2>(), _container.Resolve<T3>());
}
var appModel = await container.ResolveAsync<IDependency,IDependency2>(AppModel.CreateAsync);
var-appModel=await-container.ResolveAsync(appModel.CreateAsync);

使用包装器以允许使用C#的原语类型推断:(我将节省精力,不再花更多的时间在解决问题上。

除了需要一组难看的扩展方法外,我的第一个答案将工厂的签名泄漏到调用模块中,需要引用不直接需要的名称空间。为了隐藏这一点,一个can使用相同的方案,但将依赖项集封装在
AsyncFactory
类中:-

class AppModel
{
     public class AsyncFactory
     {
           public AsyncFactory(IDependency x, IDependency2 y)
           { 
               CreateAsync = async() =>
                   new AppModel( x.CalculateA(await y.CalculateB()));
           }
           public Func<Task<AppModel> CreateAsync { get;}
     }
     private AppModel(A a) { ... }
}
类AppModel
{
公共类异步工厂
{
公共异步工厂(IDependency x,IDependency 2 y)
{ 
CreateAsync=async()=>
新的AppModel(x.CalculateA(wait y y.CalculateB());
}
public Func滥用,可以将
CreateAsync
方法转换为Autofac可以解决的问题:-一种类型[源自
LazyTask
],如下所示:

class AppModel
{
     public class AsyncFactory : LazyTask<AppModel>
     {
           public AsyncFactory(IDependency x, IDependency2 y) : base(async() => 
               new AppModel( x.CalculateA(await y.CalculateB())))
           {}
     }
     private AppModel(A a) { ... }
}

为什么这个解决方案使用标准解析方法为您提供了contra的好处?@jguaffin要澄清一点,我不希望有任何明确的注册,而是依赖于,并且我正在寻找类似的东西,作为一个例子来处理
任务
方面-但美中不足的是,CTOR不想做
异步
@jguaffin请参阅,以获得我从消费者角度所期望的封装,而无需在Autofac中进行明确注册。
class AppModel
{
     public class AsyncFactory : LazyTask<AppModel>
     {
           public AsyncFactory(IDependency x, IDependency2 y) : base(async() => 
               new AppModel( x.CalculateA(await y.CalculateB())))
           {}
     }
     private AppModel(A a) { ... }
}
var appModel = await container.Resolve<AppModel.AsyncFactory>();
class AppModel
{
    public async Task<AppModel> CreateAsync(IDependency x, IDependency2 y) =>
        new AppModel( x.CalculateA(await y.CalculateB()));
}
var appModel = await container.Resolve<Task<AppModel>>();