我正在尝试解决我在Autofac中注册的接口,但似乎无法正常工作。有 nullreferenceexception。
我注册接口的类:
public void RegisterAutofac(HttpConfiguration config)
{
var builder = new ContainerBuilder();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
(...)
builder.RegisterType<ApiFileTester>().As<IApiFlTester>().InstancePerRequest();
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}
然后我要在课堂上使用它:
public class ApiFileSendingController : ApiClientBase
{
private readonly IApiFlTester _apiFileTester;
public ApiFileSendingController(DTO dto, IApiFlTester tester) : base(dto)
{
_tester = tester;
}
public void Send(List<AftInvFileDTO> filesToSendRetry = null)
{
_apiFileTester.RegisterTestingMethods();
}
}
然后在其他一些班上:
DTO dto = new DTO(); //some configuration here
ApiFileSendingController sender = new ApiFileSendingController(dto, null);
sender.Send();
这里有一个问题,因为我的界面为空。我试图这样传递它:
ApiFileSendingController发送者=新的ApiFileSendingController(dto, null);
,但它为null,并且是完全合理的(我通过了null)。 是否可以配置可选参数?我想让这个界面通过autofac自动解决,而不是手动解决。
答案 0 :(得分:0)
在解决您的课程时,我似乎没有问题。从技术上讲,不可能真正回答您的问题,因为该代码甚至无法编译,并且看来您丢失了大量的autofac注册。
// @nuget: Autofac
using System;
using Autofac;
public class Program
{
private static IContainer _container;
public static void Main()
{
RegisterAutofac();
using (var httpRequestScope = _container.BeginLifetimeScope("AutofacWebRequest"))
{
var apiController = httpRequestScope.Resolve<ApiFileSendingController>();
Console.WriteLine(apiController._apiFileTester);
}
}
public static void RegisterAutofac()
{
var builder = new ContainerBuilder();
//builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterType<ApiFileTester>().As<IApiFlTester>().InstancePerLifetimeScope();
builder.RegisterType<ApiFileSendingController>().AsSelf();
builder.RegisterType<DTO>().AsSelf();
_container = builder.Build();
}
public class ApiFileSendingController : ApiClientBase
{
public readonly IApiFlTester _apiFileTester;
public ApiFileSendingController(DTO dto, IApiFlTester tester): base (dto)
{
_apiFileTester = tester;
}
}
public interface IApiFlTester { }
public class ApiFileTester : IApiFlTester { }
public class ApiClientBase
{
public ApiClientBase(DTO dto)
{
}
}
public class DTO { }
}
答案 1 :(得分:-1)
您对Autofac DI有误解,大多数DI框架都擅长为您创建实例,通过构造函数注入和属性注入,您将获得实例及其依赖关系自动连接的实例。 您的构造函数包含您将在运行时提供的DTO实例,由于您在ConfigureServices周期中未将其声明给DI容器,因此Autofac不会解决该问题。
在这种情况下,您可能需要放弃使用Autofac来自由地在自己的代码中创建控制器实例,而您需要从Reflection中获取具体的类实例。通过这种方法仍然可以实现抽象/实现隔离。
公共类ApiFileSendingController:ApiClientBase { 私有只读IApiFlTester _apiFileTester;
public ApiFileSendingController(DTO dto, IApiFlTester tester) : base(dto)
{
if (tester is null)
_tester = GetApiTesterViaReflection();
else
_tester = tester;
}
public ApiFileSendingController(DTO dto) : base(dto)
{
_apiFileTester = GetApiTesterViaReflection();
}
public void Send(List<AftInvFileDTO> filesToSendRetry = null)
{
_apiFileTester.RegisterTestingMethods();
}
private IApiFlTester GetApiTesterViaReflection()
{
Type type = typeof(IApiFlTester).Assembly.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IApiFlTester))).FirstOrDefault();
return Activator.CreateInstance(type) as IApiFlTester;
}
}