【问题标题】:Injecting an instance of a service with Autofac使用 Autofac 注入服务实例
【发布时间】:2016-09-07 20:39:41
【问题描述】:

我对@9​​87654321@ 注入或注册有疑问。 这是我的代码

存储库

 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 才能从此类内的数据库中获取数据:

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

任何帮助将不胜感激!提前致谢。

【问题讨论】:

  • 嗨@Ahmed MHAMMI我不知道,在你的类CustomDisplayNameAttribute中,你什么时候初始化mappingBaseService?
  • 您好,感谢您的回复,我必须在 autofac init 中对其进行初始化,但我不知道如何
  • 如果你想让它工作,你应该在 GetMessageFromResource 中添加新参数,例如:GetMessageFromResource(string value, IMappingBaseService _mappingBaseService)。并将其分配给您的属性中的 IMappingBaseService。
  • 我不能将它作为参数传递给属性
  • 为什么?现在您的属性中的属性 mappingBaseService 为空。如果你不为某事分配它,它就不起作用

标签: c# asp.net-mvc .net-4.5 autofac ioc-container


【解决方案1】:

代码演示如:

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

【讨论】:

    【解决方案2】:

    也许你可以修复代码注册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();
    

    【讨论】:

    • 总是 mappingBaseService null :/
    • 你可以尝试添加寄存器IMappingBaseService。
    • mappingBaseService 在哪里为空?
    • 在自定义显示名称属性中
    【解决方案3】:

    解决方案是使用属性注入(在 autofac init 中实例化类)

    我们必须添加这一行

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

    在 CustomDisplayNameAttribute 中我们添加空构造函数

    public CustomDisplayNameAttribute() {}
    

    public IMappingBaseService _mappingBaseService { get; set; }
    

    以及获取我们使用的对象

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

    【讨论】:

      【解决方案4】:

      问题是我从 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; }
          }
      

      我有这个错误

      错误 3 属性参数必须是常量表达式 typeof 属性参数的表达式或数组创建表达式 类型 D:\CDS_ADMIN\ClientConfiguration.Web\ViewModel\ClientElementsViewModel.cs 22 32 ClientConfiguration.Web

      【讨论】:

      • 我必须附加 DisplayNameAttribute 才能从 DB 获取 fata,但即使这样,它也不起作用!!
      • 你为我筛选数据库设计吗?
      • 这只是一个映射显示名称的表。没有数据库(我不需要其他表)
      • public class MappingBase { [Key] public long MappingBaseId { get;放; } 公共字符串表名 { 获取;放; } 公共字符串参数名称 { 获取;放; } 公共字符串参数显示 { 获取;放; } 公共字符串参数注释 { 获取;放;例如,我必须将 CompanyCode 映射到此表中的等效值,以便在我的视图中显示它
      • No _mappingBaseService 始终为空(没有实例)
      猜你喜欢
      • 2011-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-21
      相关资源
      最近更新 更多