castle windsor 仅在实现不是抽象或接口的情况下注册服务和实现
castle windsor registering service and implementation only where implementation is not abstract or interface
我的所有服务及其域接口都在一个项目中,存储库在另一个项目中。我使用以下代码注册程序集:
public IWindsorContainer SetupWithWebRequest()
{
return Generate(c => c.LifestylePerWebRequest());
}
public WindsorContainer SetupWithThread()
{
return Generate(c => c.LifestylePerThread());
}
private WindsorContainer Generate(Action<ComponentRegistration> reg)
{
var container = new WindsorContainer();
var types = new List<FromAssemblyDescriptor>();
types.Add(Types.FromAssembly(typeof(BlogRepository).Assembly));
types.Add(Types.FromAssembly(typeof(BlogEntryService).Assembly));
foreach (var type in types)
{
container.Register(type.Pick().WithServiceAllInterfaces().Configure(reg));
}
//ensure the db context is passed in.
container.Register(Component.For<IUserRepository<BlogUserEntity, int>>().LifeStyle.PerWebRequest.UsingFactoryMethod(() => new GenericUserRepository<BlogUserEntity, int>(new BlogEngineContext())));
return container;
}
上面的代码会注册很多我不感兴趣的东西。例如所有 IDisposable 的东西。这可能不是问题,不知道它是否会减慢速度?我的主要问题是我在域层中定义了一个接口,但它是在网站中实现的。
以上代码在域DLL内,从网站(global.asax)调用,如下:
var container = new WindsorContainerGeneration().SetupWithWebRequest();
container.RegisterControllers(Assembly.GetExecutingAssembly());
//setup the website to get its user from aspnet.
container.Register(Component.For<IGetCurrentUserName>().LifeStyle.PerWebRequest.ImplementedBy(typeof(GetCurrentUserNameUsingAspnet)));
GlobalConfiguration.Configuration.DependencyResolver = new WindsorDependencyResolver(container);
ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container));
即使我手动注册了 IGetCurrentUserName 的实例,容器也已经注册了一个实例,其中服务和实现都是接口。
有没有办法确保只有 类 实现了一个接口才被注册,而不是在上面注册?
您可以过滤到仅使用 types.BasedOn<IInterfaceName>()
实现特定接口的 类
如果您只想过滤到实现了任何接口的类,您可以使用这个:
types.Where(type => type.GetInterfaces().Any()
这是一个示例实现:
protected virtual IEnumerable<IRegistration> GetComponentRegistrations()
{
return new IRegistration[]
{
Classes.FromAssembly(GetAssemblyNamed(MyAssembly))
.BasedOn<IMyComponent>()
.If(x => x.IsContructable()) // this is it
.WithServiceDefaultInterfaces()
};
}
public static class TypeHelpers
{
public static bool IsContructable(this Type t)
{
return !t.IsAbstract && !t.ContainsGenericParameters;
}
}
我的所有服务及其域接口都在一个项目中,存储库在另一个项目中。我使用以下代码注册程序集:
public IWindsorContainer SetupWithWebRequest()
{
return Generate(c => c.LifestylePerWebRequest());
}
public WindsorContainer SetupWithThread()
{
return Generate(c => c.LifestylePerThread());
}
private WindsorContainer Generate(Action<ComponentRegistration> reg)
{
var container = new WindsorContainer();
var types = new List<FromAssemblyDescriptor>();
types.Add(Types.FromAssembly(typeof(BlogRepository).Assembly));
types.Add(Types.FromAssembly(typeof(BlogEntryService).Assembly));
foreach (var type in types)
{
container.Register(type.Pick().WithServiceAllInterfaces().Configure(reg));
}
//ensure the db context is passed in.
container.Register(Component.For<IUserRepository<BlogUserEntity, int>>().LifeStyle.PerWebRequest.UsingFactoryMethod(() => new GenericUserRepository<BlogUserEntity, int>(new BlogEngineContext())));
return container;
}
上面的代码会注册很多我不感兴趣的东西。例如所有 IDisposable 的东西。这可能不是问题,不知道它是否会减慢速度?我的主要问题是我在域层中定义了一个接口,但它是在网站中实现的。
以上代码在域DLL内,从网站(global.asax)调用,如下:
var container = new WindsorContainerGeneration().SetupWithWebRequest();
container.RegisterControllers(Assembly.GetExecutingAssembly());
//setup the website to get its user from aspnet.
container.Register(Component.For<IGetCurrentUserName>().LifeStyle.PerWebRequest.ImplementedBy(typeof(GetCurrentUserNameUsingAspnet)));
GlobalConfiguration.Configuration.DependencyResolver = new WindsorDependencyResolver(container);
ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container));
即使我手动注册了 IGetCurrentUserName 的实例,容器也已经注册了一个实例,其中服务和实现都是接口。
有没有办法确保只有 类 实现了一个接口才被注册,而不是在上面注册?
您可以过滤到仅使用 types.BasedOn<IInterfaceName>()
如果您只想过滤到实现了任何接口的类,您可以使用这个:
types.Where(type => type.GetInterfaces().Any()
这是一个示例实现:
protected virtual IEnumerable<IRegistration> GetComponentRegistrations()
{
return new IRegistration[]
{
Classes.FromAssembly(GetAssemblyNamed(MyAssembly))
.BasedOn<IMyComponent>()
.If(x => x.IsContructable()) // this is it
.WithServiceDefaultInterfaces()
};
}
public static class TypeHelpers
{
public static bool IsContructable(this Type t)
{
return !t.IsAbstract && !t.ContainsGenericParameters;
}
}