首页 > 代码库 > Autofac 的点滴

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 adaptedbuilder.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?

Autofac 的点滴