• Autofac 的点滴


    泛型类型的注册和使用

    public interface IRepository<T> where T:class
    {
    }
    
    public interface ISchoolDetailRepository : IRepository<SchoolDetail>
    {
    }
    
    public abstract class RepositoryBase<T> where T : class
    {
    private LearningCompactPilotContext _dataContext;
    private readonly IDbSet<T> _dbset;
    protected RepositoryBase(IDatabaseFactory databaseFactory)
    {
        DatabaseFactory = databaseFactory;
        _dbset = DataContext.Set<T>();
    }
    
    protected IDatabaseFactory DatabaseFactory
    {
        get; private set;
    }
    
    protected LearningCompactPilotContext DataContext
    {
        get { return _dataContext ?? (_dataContext = DatabaseFactory.Get()); }
    }
    
    //... more code
    }
    
    //如何注册
    
    builder.RegisterGeneric(typeof(RepositoryBase<>))
       .As(typeof(IRepository<>));
    
    //如何使用
    public class SomeService
    {
        private readonly IRepository<SomeEntity> _repository;
    
        public SchoolService(IRepository<SomeEntity> repository)
        {
            this._repository= repository;
        }
    }

    如何注入泛型的Nloggger<T>  AS ILogger(动态类型注入)

    public class LoggingModule : Autofac.Module
    {
      private static void InjectLoggerProperties(object instance)
      {
        var instanceType = instance.GetType();
    
        // Get all the injectable properties to set.
        // If you wanted to ensure the properties were only UNSET properties,
        // here's where you'd do it.
        var properties = instanceType
          .GetProperties(BindingFlags.Public | BindingFlags.Instance)
          .Where(p => p.PropertyType == typeof(ILog) && p.CanWrite && p.GetIndexParameters().Length == 0);
    
        // Set the properties located.
        foreach (var propToSet in properties)
        {
          propToSet.SetValue(instance, LogManager.GetLogger(instanceType), null);
        }
      }
    
      private static void OnComponentPreparing(object sender, PreparingEventArgs e)
      {
        e.Parameters = e.Parameters.Union(
          new[]
          {
            new ResolvedParameter(
                (p, i) => p.ParameterType == typeof(ILog),
                (p, i) => LogManager.GetLogger(p.Member.DeclaringType)
            ),
          });
      }
    
      protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
      {
        // Handle constructor parameters.
        registration.Preparing += OnComponentPreparing;
    
        // Handle properties.
        registration.Activated += (sender, e) => InjectLoggerProperties(e.Instance);
      }
    }

    相同接口不同实现的如何注册使用

    适配模式和装饰模式注册

    适配模式

    var builder = new ContainerBuilder();
    
    // Register the services to be adapted
    builder.RegisterType<SaveCommand>()
           .As<ICommand>()
           .WithMetadata("Name", "Save File");
    builder.RegisterType<OpenCommand>()
           .As<ICommand>()
           .WithMetadata("Name", "Open File");
    
    // Then register the adapter. In this case, the ICommand
    // registrations are using some metadata, so we're
    // adapting Meta<ICommand> instead of plain ICommand.
    builder.RegisterAdapter<Meta<ICommand>, ToolbarButton>(
       cmd => new ToolbarButton(cmd.Value, (string)cmd.Metadata["Name"]));
    
    var container = builder.Build();
    
    // The resolved set of buttons will have two buttons
    // in it - one button adapted for each of the registered
    // ICommand instances.
    var buttons = container.Resolve<IEnumerable<ToolbarButton>>();

    装饰模式

    var builder = new ContainerBuilder();
    
    // Register the services to be decorated. You have to
    // name them rather than register them As<ICommandHandler>()
    // so the *decorator* can be the As<ICommandHandler>() registration.
    builder.RegisterType<SaveCommandHandler>()
           .Named<ICommandHandler>("handler");
    builder.RegisterType<OpenCommandHandler>()
           .Named<ICommandHandler>("handler");
    
    // Then register the decorator. The decorator uses the
    // named registrations to get the items to wrap.
    builder.RegisterDecorator<ICommandHandler>(
        (c, inner) => new CommandHandlerDecorator(inner),
        fromKey: "handler");
    
    var container = builder.Build();
    
    // The resolved set of commands will have two items
    // in it, both of which will be wrapped in a CommandHandlerDecorator.
    var handlers = container.Resolve<IEnumerable<ICommandHandler>>();

    还是使用泛型

    var builder = new ContainerBuilder();
    
    // Register the open generic with a name so the
    // decorator can use it.
    builder.RegisterGeneric(typeof(CommandHandler<>))
           .Named("handler", typeof(ICommandHandler<>));
    
    // Register the generic decorator so it can wrap
    // the resolved named generics.
    builder.RegisterGenericDecorator(
            typeof(CommandHandlerDecorator<>),
            typeof(ICommandHandler<>),
            fromKey: "handler");
    
    var container = builder.Build();
    
    // You can then resolve closed generics and they'll be
    // wrapped with your decorator.
    var mailHandlers = container.Resolve<IEnumerable<ICommandHandler<EmailCommand>>>();
     

    参考

    MVC 4 Autofac and Generic Repository pattern

    log4net Integration Module

    Adapters and Decorators

    How do I pick a service implementation by context?

    Selectively resolving services at runtime with Autofac

  • 相关阅读:
    亿级流量架构服务降级,写得太好了!
    面试官:什么是对象池?有什么用?别说你还不会!
    最新数据库排行榜出炉!MySQL 稳了~
    别再写满屏的 get & set 了,太 Low!试试 MapStruct 高级玩法!
    vista 中php4, php5 共存
    dotnet framework 3.5 installed issues on nonenglish os
    web service notes
    msn web status
    db notes
    wikipedia的mysql utf8中文在.net中的处理
  • 原文地址:https://www.cnblogs.com/HQFZ/p/5915092.html
Copyright © 2020-2023  润新知