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