简体   繁体   English

使用Autofac注入服务的实例

[英]Injecting an instance of a service with Autofac

I have a problem with Autofac injection or registration. 我对Autofac注入或注册有问题。 This is my code 这是我的代码

Repository 资料库

 namespace ClientConfiguration.Data.Repository
 {
     public class MappingBaseRepository : RepositoryBase<MappingBase>, IMappingBaseRepository
     {
         public MappingBaseRepository(IDatabaseFactory databaseFactory)
                 : base(databaseFactory)
         {
         }

     }

     public interface IMappingBaseRepository : IRepository<MappingBase>
     {  
     }
 }

Service 服务

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 init 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));
        }

Now if I'm inside a controller I have an instance of the service objects without problem. 现在,如果我在控制器内部,则可以毫无问题地获得服务对象的实例。 But I have to access my service IMappingBaseService to get data from DB inside this class: 但是我必须访问我的服务IMappingBaseService才能从此类内的DB获取数据:

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 "";
        }
    }
}

Any help would be greatly appreciated! 任何帮助将不胜感激! Thanks in advance. 提前致谢。

Code demo such as: 代码演示,例如:

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 "";
        }
    }
}

Maybe you can fix code register autofac, Because autofac only register for interface such as: 也许您可以修复代码注册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();

The solution was to use Property injection (instanciate the class inside the autofac init) 解决的办法是使用属性注入(实例化autofac init内的类)

We have to add this line 我们必须添加这一行

builder.Register(c => new CustomDisplayNameAttribute {
_mappingBaseService = c.Resolve<IMappingBaseService>() });

and in CustomDisplayNameAttribute we add empty constructor 然后在CustomDisplayNameAttribute中添加空的构造函数

public CustomDisplayNameAttribute() {}

and

public IMappingBaseService _mappingBaseService { get; set; }

and for getting the object we use 为了获得对象,我们使用

var _mappingBaseService = DependencyResolver.Current.GetService<IMappingBaseService>();

The problem is that is i surcharge CustomDisplayName from DisplayNameAttribute (ASP.NET MVC) 问题是我从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; }
    }

I have this error 我有这个错误

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 错误3属性参数必须是属性参数类型D:\\ CDS_ADMIN \\ ClientConfiguration.Web \\ ViewModel \\ ClientElementsViewModel.cs的常数表达式,typeof表达式或数组创建表达式22 32 ClientConfiguration.Web

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM