使用 Autofac 注入服务实例
Injecting an instance of a service with Autofac
我在 Autofac
注入或注册方面遇到问题。
这是我的代码
存储库
namespace ClientConfiguration.Data.Repository
{
public class MappingBaseRepository : RepositoryBase<MappingBase>, IMappingBaseRepository
{
public MappingBaseRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
}
}
public interface IMappingBaseRepository : IRepository<MappingBase>
{
}
}
服务
namespace ClientConfiguration.Service {
public interface IMappingBaseService
{
IEnumerable<MappingBase> GetElements();
void SaveElement();
}
public class MappingBaseService : IMappingBaseService
{
private readonly IMappingBaseRepository MappingBaseRepository;
private readonly IUnitOfWork unitOfWork;
public MappingBaseService(IMappingBaseRepository MappingBaseRepository, IUnitOfWork unitOfWork)
{
this.MappingBaseRepository = MappingBaseRepository;
this.unitOfWork = unitOfWork;
}
#region Members
public IEnumerable<MappingBase> GetElements()
{
var Elements = MappingBaseRepository.GetAll();
return Elements;
}
public void SaveElement()
{
unitOfWork.Commit();
}
#endregion
} }
Autofac 初始化
private static void SetAutofacContainer() {
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerRequest();
builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>().InstancePerRequest();
// Repositories
builder.RegisterAssemblyTypes(typeof(ClientElementRepository).Assembly)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces().InstancePerRequest();
// Services
builder.RegisterAssemblyTypes(typeof(ClientElementService).Assembly)
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces().InstancePerRequest();
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
现在,如果我在控制器内,我就有一个服务对象的实例,没有问题。但是我必须访问我的服务 IMappingBaseService
才能从这个 class 中的数据库获取数据:
namespace ClientConfiguration.Mappings {
public class CustomDisplayNameAttribute : DisplayNameAttribute {
private static IMappingBaseService mappingBaseService { get; set; }
public CustomDisplayNameAttribute(string value)
: base(GetMessageFromResource(value)) {
}
private static string GetMessageFromResource(string value) {
var els = mappingBaseService.GetElements().ToList();
//get value from DB
//mappingBaseService is always null
return "";
}
}
}
如有任何帮助,我们将不胜感激!提前致谢。
代码演示如:
namespace ClientConfiguration.Mappings {
public class CustomDisplayNameAttribute : DisplayNameAttribute {
private static IMappingBaseService _mappingBaseService { get; set; }
public CustomDisplayNameAttribute(string value, IMappingBaseService mappingBaseService)
: base(GetMessageFromResource(value, mappingBaseService)) {
}
private static string GetMessageFromResource(string value, IMappingBaseService mappingBaseService) {
_mappingBaseService = mappingBaseService;
var els = _mappingBaseService .GetElements().ToList();
//OR var els = mappingBaseService.GetElements().ToList();
//get value from DB
//mappingBaseService is always null
return "";
}
}
}
问题是我从 DisplayNameAttribute (ASP.NET MVC) 中附加了 CustomDisplayName
public class ClientElementsViewModel {
private static IMappingBaseService _mappingBaseService;
public ClientElementsViewModel(IMappingBaseService mappingBaseService) {
_mappingBaseService = mappingBaseService;
}
[Key]
[Display(Name = "Id")]
public long ClientElementId { get; set; }
[CustomDisplayName("", _mappingBaseService)]
public string CompanyCode { get; set; }
//[CustomDisplayName("")]
public string WebAppBaseUrl { get; set; }
//[CustomDisplayName("")]
public string GuestTraveller { get; set; }
}
我有这个错误
Error 3 An attribute argument must be a constant expression, typeof
expression or array creation expression of an attribute parameter
type D:\CDS_ADMIN\ClientConfiguration.Web\ViewModel\ClientElementsViewModel.cs 22 32 ClientConfiguration.Web
也许你可以修复代码注册autofac,因为autofac只注册接口,例如:
builder.RegisterAssemblyTypes(typeof(IClientElementRepository).Assembly)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces().InstancePerRequest();
// Services
builder.RegisterAssemblyTypes(typeof(IClientElementService).Assembly)
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces().InstancePerRequest();
builder.RegisterAssemblyTypes(typeof(IMappingBaseService).Assembly)
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces().InstancePerRequest();
解决方案是使用 属性 注入(在 autofac init 中实例化 class)
我们必须添加这一行
builder.Register(c => new CustomDisplayNameAttribute {
_mappingBaseService = c.Resolve<IMappingBaseService>() });
并在 CustomDisplayNameAttribute 中添加空构造函数
public CustomDisplayNameAttribute() {}
和
public IMappingBaseService _mappingBaseService { get; set; }
为了获取我们使用的对象
var _mappingBaseService = DependencyResolver.Current.GetService<IMappingBaseService>();
我在 Autofac
注入或注册方面遇到问题。
这是我的代码
存储库
namespace ClientConfiguration.Data.Repository
{
public class MappingBaseRepository : RepositoryBase<MappingBase>, IMappingBaseRepository
{
public MappingBaseRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
}
}
public interface IMappingBaseRepository : IRepository<MappingBase>
{
}
}
服务
namespace ClientConfiguration.Service {
public interface IMappingBaseService
{
IEnumerable<MappingBase> GetElements();
void SaveElement();
}
public class MappingBaseService : IMappingBaseService
{
private readonly IMappingBaseRepository MappingBaseRepository;
private readonly IUnitOfWork unitOfWork;
public MappingBaseService(IMappingBaseRepository MappingBaseRepository, IUnitOfWork unitOfWork)
{
this.MappingBaseRepository = MappingBaseRepository;
this.unitOfWork = unitOfWork;
}
#region Members
public IEnumerable<MappingBase> GetElements()
{
var Elements = MappingBaseRepository.GetAll();
return Elements;
}
public void SaveElement()
{
unitOfWork.Commit();
}
#endregion
} }
Autofac 初始化
private static void SetAutofacContainer() {
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerRequest();
builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>().InstancePerRequest();
// Repositories
builder.RegisterAssemblyTypes(typeof(ClientElementRepository).Assembly)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces().InstancePerRequest();
// Services
builder.RegisterAssemblyTypes(typeof(ClientElementService).Assembly)
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces().InstancePerRequest();
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
现在,如果我在控制器内,我就有一个服务对象的实例,没有问题。但是我必须访问我的服务 IMappingBaseService
才能从这个 class 中的数据库获取数据:
namespace ClientConfiguration.Mappings {
public class CustomDisplayNameAttribute : DisplayNameAttribute {
private static IMappingBaseService mappingBaseService { get; set; }
public CustomDisplayNameAttribute(string value)
: base(GetMessageFromResource(value)) {
}
private static string GetMessageFromResource(string value) {
var els = mappingBaseService.GetElements().ToList();
//get value from DB
//mappingBaseService is always null
return "";
}
}
}
如有任何帮助,我们将不胜感激!提前致谢。
代码演示如:
namespace ClientConfiguration.Mappings {
public class CustomDisplayNameAttribute : DisplayNameAttribute {
private static IMappingBaseService _mappingBaseService { get; set; }
public CustomDisplayNameAttribute(string value, IMappingBaseService mappingBaseService)
: base(GetMessageFromResource(value, mappingBaseService)) {
}
private static string GetMessageFromResource(string value, IMappingBaseService mappingBaseService) {
_mappingBaseService = mappingBaseService;
var els = _mappingBaseService .GetElements().ToList();
//OR var els = mappingBaseService.GetElements().ToList();
//get value from DB
//mappingBaseService is always null
return "";
}
}
}
问题是我从 DisplayNameAttribute (ASP.NET MVC) 中附加了 CustomDisplayName
public class ClientElementsViewModel {
private static IMappingBaseService _mappingBaseService;
public ClientElementsViewModel(IMappingBaseService mappingBaseService) {
_mappingBaseService = mappingBaseService;
}
[Key]
[Display(Name = "Id")]
public long ClientElementId { get; set; }
[CustomDisplayName("", _mappingBaseService)]
public string CompanyCode { get; set; }
//[CustomDisplayName("")]
public string WebAppBaseUrl { get; set; }
//[CustomDisplayName("")]
public string GuestTraveller { get; set; }
}
我有这个错误
Error 3 An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type D:\CDS_ADMIN\ClientConfiguration.Web\ViewModel\ClientElementsViewModel.cs 22 32 ClientConfiguration.Web
也许你可以修复代码注册autofac,因为autofac只注册接口,例如:
builder.RegisterAssemblyTypes(typeof(IClientElementRepository).Assembly)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces().InstancePerRequest();
// Services
builder.RegisterAssemblyTypes(typeof(IClientElementService).Assembly)
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces().InstancePerRequest();
builder.RegisterAssemblyTypes(typeof(IMappingBaseService).Assembly)
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces().InstancePerRequest();
解决方案是使用 属性 注入(在 autofac init 中实例化 class)
我们必须添加这一行
builder.Register(c => new CustomDisplayNameAttribute {
_mappingBaseService = c.Resolve<IMappingBaseService>() });
并在 CustomDisplayNameAttribute 中添加空构造函数
public CustomDisplayNameAttribute() {}
和
public IMappingBaseService _mappingBaseService { get; set; }
为了获取我们使用的对象
var _mappingBaseService = DependencyResolver.Current.GetService<IMappingBaseService>();