使用 Scrutor 自动依赖注入
Automatic dependency injecting using Scrutor
我的项目中有许多服务,并尝试使用 Scrutor 进行自动 DI,而不是在 startup.cs
上手动注册每个服务
BarService.cs
public class BarService : IBar
{
public Bar Get(int id)
{
var bar = new Bar
{
bar_date = DateTime.UtcNow,
bar_name = "bar"
};
return bar;
}
public List<Bar> GetMany()
{
List<Bar> list = new List<Bar>
{
new Bar
{
bar_date = DateTime.UtcNow,
bar_name = "bar 1"
},
new Bar
{
bar_date = DateTime.UtcNow,
bar_name = "bar 2"
}
};
return list;
}
}
IBar.cs
public interface IBar
{
Bar Get(int id);
List<Bar> GetMany();
}
Bar.cs
public class Bar
{
public string bar_name { get; set; }
public DateTime bar_date { get; set; }
}
BarController.cs
[Route("api/[controller]")]
[ApiController]
public class BarController : ControllerBase
{
public IBar _service { get; set; }
public BarController(IBar service)
{
_service = service;
}
[HttpGet("{id:int}")]
public IActionResult Get(int id)
{
var result = _service.Get(id);
if (result != null)
{
return Ok(result);
}
return NotFound("No data found");
}
[HttpGet]
public IActionResult GetMany()
{
var result = _service.GetMany();
if (result != null)
{
return Ok(result);
}
return NotFound("No data found");
}
}
将 services.AddScoped<IBar, BarService>();
添加到 Startup.cs 可以正常工作,但不能使用 Scrutor 自动映射。
services.Scan(scan =>
scan.FromCallingAssembly()
.AddClasses()
.AsMatchingInterface());
我收到错误
@Vikash Rathee,你可以试试AsImplementedInterfaces()
。它将每个匹配的具体类型注册为其所有已实现的接口。
services.Scan(scan =>
scan.FromCallingAssembly()
.AddClasses()
.AsImplementedInterfaces());
结果如下图
您目前正在使用AsMatchingInterface()
,
Registers services which match a standard naming convention
这将适用于如下所示的比赛。
public class BarService : IBarService
在你的例子中
public class BarService : IBar
不遵循该约定,因此不提供您预期的行为
因此,要么重构您的接口以遵循 Scrutor 预期的抽象和实现之间的命名约定,
或使用AsImplementedInterfaces()
,即
Registers an implementation as all implemented interfaces
但是请注意,除非提供生命周期,否则默认情况下这会将这些接口注册为单例。
我建议将它们注册为作用域。
我的项目中有许多服务,并尝试使用 Scrutor 进行自动 DI,而不是在 startup.cs
上手动注册每个服务BarService.cs
public class BarService : IBar
{
public Bar Get(int id)
{
var bar = new Bar
{
bar_date = DateTime.UtcNow,
bar_name = "bar"
};
return bar;
}
public List<Bar> GetMany()
{
List<Bar> list = new List<Bar>
{
new Bar
{
bar_date = DateTime.UtcNow,
bar_name = "bar 1"
},
new Bar
{
bar_date = DateTime.UtcNow,
bar_name = "bar 2"
}
};
return list;
}
}
IBar.cs
public interface IBar
{
Bar Get(int id);
List<Bar> GetMany();
}
Bar.cs
public class Bar
{
public string bar_name { get; set; }
public DateTime bar_date { get; set; }
}
BarController.cs
[Route("api/[controller]")]
[ApiController]
public class BarController : ControllerBase
{
public IBar _service { get; set; }
public BarController(IBar service)
{
_service = service;
}
[HttpGet("{id:int}")]
public IActionResult Get(int id)
{
var result = _service.Get(id);
if (result != null)
{
return Ok(result);
}
return NotFound("No data found");
}
[HttpGet]
public IActionResult GetMany()
{
var result = _service.GetMany();
if (result != null)
{
return Ok(result);
}
return NotFound("No data found");
}
}
将 services.AddScoped<IBar, BarService>();
添加到 Startup.cs 可以正常工作,但不能使用 Scrutor 自动映射。
services.Scan(scan =>
scan.FromCallingAssembly()
.AddClasses()
.AsMatchingInterface());
我收到错误
@Vikash Rathee,你可以试试AsImplementedInterfaces()
。它将每个匹配的具体类型注册为其所有已实现的接口。
services.Scan(scan =>
scan.FromCallingAssembly()
.AddClasses()
.AsImplementedInterfaces());
结果如下图
您目前正在使用AsMatchingInterface()
,
Registers services which match a standard naming convention
这将适用于如下所示的比赛。
public class BarService : IBarService
在你的例子中
public class BarService : IBar
不遵循该约定,因此不提供您预期的行为
因此,要么重构您的接口以遵循 Scrutor 预期的抽象和实现之间的命名约定,
或使用AsImplementedInterfaces()
,即
Registers an implementation as all implemented interfaces
但是请注意,除非提供生命周期,否则默认情况下这会将这些接口注册为单例。
我建议将它们注册为作用域。