我想使用 Func
我想包装Autofac Register方法(带有lambda表达式),例如此处https://autofaccn.readthedocs.io/en/latest/register/registration.html#lambda-expression-components
我某种程度上需要转换
Func<IDependencyContainer, T> delegate1
到
Func<IComponentContext, T> delegate1
这是我当前的尝试样子:
public IDependencyContainerToAddOptions<T> WrapperRegister<T>
(
Func<IDependencyContainer, T> delegate1
)
{
return new DependencyContainerToAddOptions<T>(_containerBuilder.Register(delegate1));
}
TLDR:
如何包装Autofac的Register方法,可以这样调用:
_builder.Register(ctx =>
{ var profileService = ctx.Resolve<IUserProfileService>();
,其定义如下:
/// <summary>
/// Register a delegate as a component.
/// </summary>
/// <typeparam name="T">The type of the instance.</typeparam>
/// <param name="builder">Container builder.</param>
/// <param name="delegate">The delegate to register.</param>
/// <returns>Registration builder allowing the registration to be configured.</returns>
public static IRegistrationBuilder<T, SimpleActivatorData, SingleRegistrationStyle>
Register<T>(
this ContainerBuilder builder,
Func<IComponentContext, T> delegate1)
{
if (delegate1 == null) throw new ArgumentNullException(nameof(delegate1));
return builder.Register((c, p) => delegate1(c));
}
包装程序的用户不必向Autofac添加依赖项。
答案 0 :(得分:1)
您尝试做的事情似乎与this FAQ in the Autofac docs asking how to keep Autofac references out of your app.有很多重叠,特别是,您在问如何有效地复制Autofac的某些注册语法,我想这样您的应用程序就可以注册内容而无需引用Autofac。
这样做有很多充分的理由,但是我可能会说服您不要这样做。如该常见问题解答所述:
您可能会花费大量时间来编写事物的抽象和包装,而只是复制许多特定于Autofac的语法和功能。
这种“将自己与引用隔离”的情况在日志记录中也经常发生,而且也没有很多超好的解决方案。
随着.NET Core的出现,一种方法是使用Microsoft.Extensions.DependencyInjection抽象。使用IServiceCollection
在此处注册内容,然后即可使用the Autofac.Extensions.DependencyInjection package to push those registrations into an Autofac container。这限制了您对抽象的支持,但是却为您提供了不必维护的抽象。
但是,再说一次,您确实要维护自己的。如果您想让人们注册Func<IComponentContext, T>
,那么您应该意识到IComponentContext
是Autofac的事情,这打破了您的孤立感。您在底部的更新中提到,希望您的用户不要引用Autofac ...,但是再次考虑,您需要镜像所有Autofac的行为和语法。
因此,如果要执行此操作,则需要创建包装器和抽象。很多包装和抽象。超过将值得维护。该模式将是:
类似的东西:
public interface IMyComponentContext
{
T Resolve<T>();
}
public class ComponentContextWrapper : IMyComponentContext
{
private readonly IComponentContext _autofacContext;
public ComponentContextWrapper(IComponentContext autofacContext)
{
_autofacContext = autofacContext;
}
public T Resolve<T>()
{
return this._autofacContext.Resolve<T>();
}
}
将会很多。然后...
IComponentContext
创建一个包装器。// In the place where you actually register your delegates, you'll have
// to provide wrappers for your clients:
builder.Register((c, p) => delegate1(new ComponentContextWrapper(c)));
如果我还没有说清楚的话,我强烈认为这是一个坏主意。这是很多工作,除非真的有一些潜在的需求要离开Autofac,否则维护抽象,测试抽象等没有真正的收获。但是,如果要保持这种分离,这就是您需要做的。祝你好运!