泛型类型的注册和使用
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