I am trying to build out a structure where I have a base IValidator<> interface that will be generated for our system based on some metadata. We want to give future developers the flexibility to 1) Regenerate the concrete implementations of IValidator<> if need be without disturbing any hand-written code and 2) Add decorators to IValidator<> to be able to extend the functionality without disturbing the auto-generated code.
I would like to have some way to resolve the generic decorators at runtime using the RegisterDecorator method of Simple Injector so our dev team does not need to go and update the composition root every time we add a decorator.
Here are some example classes/interfaces
public interface IValidator<T> where T : class
{
void Validate(T entity);
}
public class ClientValidator : IValidator<Client>
{
public void Validate(Client entity)
{
//Auto-generated
}
}
public class UserValidator : IValidator<User>
{
public void Validate(User entity)
{
//Auto-generated
}
}
public class ClientValidatorDecorator : IValidator<Client>
{
private readonly IValidator<Client> clientValidator;
public ClientValidatorDecorator(IValidator<Client> clientValidator)
{
this.clientValidator = clientValidator;
}
public void Validate(Client entity)
{
//New rules
this.clientValidator.Validate(entity);
}
}
public class UserValidatorDecorator : IValidator<User>
{
private readonly IValidator<User> userValidator;
public UserValidatorDecorator(IValidator<User> userValidator)
{
this.userValidator = userValidator;
}
public void Validate(User entity)
{
//New rules
this.userValidator.Validate(entity);
}
}
public class ValidationContext
{
private readonly IValidator<Client> client;
private readonly IValidator<User> user;
public ValidationContext(IValidator<Client> client, IValidator<User> user)
{
this.client = client;
this.user = user;
}
}
We I am trying to do something like so:
public void RegisterServices(Container container)
{
container.Register(typeof(IValidator<>), AssemblyManifest.GetAssemblies());
container.RegisterDecorator(typeof(IValidator<>), GetType, Lifestyle.Transient, UseType);
}
private static Type GetType(DecoratorPredicateContext ctx)
{
//Return appropriate Decorator
}
private static bool UseType(DecoratorPredicateContext ctx)
{
//Predicate
}
Unfortunately, unless I resolve a concrete type RegisterDecorator throws an error, so resolving another generic seems out. I am not sure how to proceed. Is there a way to do something like this? Is there a better way to get the intended functionality without decorators? We were thinking partial classes, but that has its own set of issues.
Any help will be appreciated!
Rather than plugging in decorators you could use a Composite Validator to enable the addition of IValidator<> implementations as required. This solution would allow the code to contain multiple IValidator<>'s for the same type.
Internally your code will still be able to depend on a single IValidator<T> which would resolve to the CompositeValidator that would call zero or more validators depending on what has been registered in the container at runtime.
The composite validator:
public class CompositeValidator<T> : IValidator<T>
{
public readonly IEnumerable<IValidator<T>> validators;
public CompositeValidator(IEnumerable<IValidator<T>> validators)
{
this.validators = validators;
}
public void Validate(T item)
{
foreach(var validator in this.validators)
{
validator.Validate(item);
}
}
}
The container is configured like this:
var assemblies = new[] { typeof(IValidator<>).Assembly };
var container = new Container();
container.RegisterCollection(typeof(IValidator<>), assemblies);
container.Register(typeof(IValidator<>), typeof(CompositeValidator<>));
where the assemblies variable contains all the assemblies you want to search for validators.
When you resolve IValidator<User> using container.GetInstance<IValidator<User>>() or through constructor injection you get back CompositeValidator<User> which internally references any and all IValidator<User>'s.
The way to get decorators of a type using batch registration is by calling the GetTypesToRegister method overload that accepts a TypesToRegisterOptions object. This way you can instruct SI to return decorators as well.
container.Register(typeof(IValidator<>), assemblies);
var t1 = container.GetTypesToRegister(typeof(IValidator<>), assemblies);
var t2 = container.GetTypesToRegister(typeof(IValidator<>), assemblies,
new TypesToRegisterOptions { IncludeDecorators = true });
foreach (Type t in t2.Except(t1)) {
container.RegisterDecorator(typeof(IValidator<>), t);
}
Do note that I do not suggest using this code. #qujck's answer addresses the design issue you have with your code, and his solutions therefore brings you to a much better place.
Related
TL;DR. I have a circular dependency and no idea how to break it.
Main.csproj: has Program.cs which manually instantiates DiService
var diService = new DiService(new Container());
diService.Register();
The register method searches CurrentDomain for assemblies and registers collections where multiple implementations exist for a given interface or else registers concretions on a 1-1 basis.
It then uses the Container to instantiate an abstract factory.
var diFactory = diService.Registry.GetInstance<IDiFactory>();
Here's the factory
public class DiFactory : IDiFactory
{
private readonly Container registry;
public DiFactory(Container registry)
{
this.registry = registry;
}
public T Get<T>()
{
var reqT = typeof(T);
return (T) registry.GetInstance(reqT);
}
}
The project dependencies in the solution look like this:
Main -> A -> B,E
B -> C,D,E
C -> D,E
D -> E
DiService and DiFactory live in project B with the other services. Not that it matters. I think I'd have the same problem if they were in Main.
All objects in projects B to E have a constructor injected DiFactory so they can decide what objects they need at run time. But for C to make use of it, it must depend on B, which is a circular dependency.
If I move the DI stuff to a new project F, then all projects can depend on that but how does the factory reference the types in the other projects without creating another circular dependency?
I followed the documentation for IRequestHandler, I just didn't do the dictionary. Most likely I have a design flaw but I can't see what it is.
Here's an example of the interactions between objects for LinqPad - doesn't compile but it looks right.
void Main()
{
var diService = new Mine.Services.MyDiService();
var diFactory = diService.Container.GetInstance<Mine.Services.IMyFactory>();
var rand = new Random();
var next = rand.Next(1, 100);
var task = next % 2 == 0
? diFactory.Get<Mine.Tasks.EvenTask>()
: (Mine.Tasks.IMyTask)diFactory.Get<Mine.Tasks.OddTask>();
task.Perform();
}
namespace Mine.Common
{
public class MyCommonObject { }
}
namespace Mine.Services
{
public class FakeContainer
{
public T GetInstance<T>() { return default(T); }
}
public interface IMyOtherService { void DoSomethingElse(); }
public class MyOtherService : IMyOtherService
{
public void DoSomethingElse()
{
throw new NotImplementedException();
}
}
public class MyService
{
private readonly IMyFactory myFactory;
public MyService(IMyFactory myFactory)
{
this.myFactory = myFactory;
}
public void MyServiceMethod()
{
var thing = myFactory.Get<Mine.Common.MyCommonObject>();
}
}
public interface IMyFactory { T Get<T>(); }
public class MyDiService
{
public FakeContainer Container;
}
public class MyFactory : IMyFactory
{
private FakeContainer Container;
public MyFactory(FakeContainer container)
{
// obviously this is really a SImple Injector Container
Container = container;
}
public T Get<T>()
{
return default(T);
}
}
}
namespace Mine.Kernel {
public interface IMyMultiConcrete { void Do(); }
public class MyConcreteBase : IMyMultiConcrete
{
protected readonly Mine.Services.IMyFactory MyFactory;
public MyConcreteBase(Mine.Services.IMyFactory myFactory)
{
MyFactory = myFactory;
}
public void Do()
{
MyFactory.Get<Mine.Common.MyCommonObject>();
}
}
public class MyConcrete1 : MyConcreteBase
{
public MyConcrete1(Mine.Services.IMyFactory myFactory) : base(myFactory) {}
public void Do()
{
MyFactory.Get<Mine.Common.MyCommonObject>();
}
}
}
namespace Mine.Tasks
{
public interface IMyTask { void Perform(); }
public class TaskBase : IMyTask
{
protected readonly Mine.Services.IMyOtherService MyOtherService;
public TaskBase(Mine.Services.IMyFactory myFactory, Mine.Services.IMyOtherService myOtherService)
{
MyOtherService = myOtherService;
}
public void Perform()
{
MyOtherService.DoSomethingElse();
}
}
public class OddTask : TaskBase
{
public OddTask(Mine.Services.IMyFactory myFactory, Mine.Services.IMyOtherService myOtherService)
: base(myFactory, myOtherService) { }
}
public class EvenTask : TaskBase
{
public EvenTask(Mine.Services.IMyFactory myFactory, Mine.Services.IMyOtherService myOtherService)
: base(myFactory, myOtherService) { }
}
}
This IDiFactory abstraction you are describing is not an implementation of the Abstract Factory design pattern—it is an implementation of the Service Locator pattern. Service Locator, however, is an anti-pattern and you should stop using it because its numerous downsides.
Instead, classes should not be able to request an unbound set of dependencies from a Service Locator, but neither should they typically be able to request a fixed set of dependencies using an Abstract Factory. Instead, classes should statically declare their required dependencies through the constructor.
This change might already fix the circular dependency as you will remove the IDiFactory (that is causing the cycle) in the first place.
DiService and DiFactory live in project B with the other services. Not that it matters.
It does matter where you wire up your dependencies. Dependencies should be wired up in your Composition Root and this Composition Root should live
As close as possible to the application’s entry point.
This most likely means that you should move this to your Console application. When you move that code, only the start-up assembly will take a dependency on the used DI Container. At that point, it becomes irrelevant to hide the DI Container behind an Abstraction (as your DiService seems to imply). Hiding is not needed anymore, because no other parts of the application except the Composition Root will have any knowledge about how dependency graphs are built. Hiding the DI Container behind an abstraction, at that point, doesn't increase maintainability any longer.
There might be an easier way, but what I typically end up doing is to have a separate assembly containing interfaces for everything I need to inject.
The main assembly (or B could do it in your case) performs the binding of interfaces to concrete implementations and everyone can reference the interfaces assembly without creating any circular dependencies.
The interface for the factory should also be in that assembly.
I'm using Autofac in an application to manage dependencies. I have an interface and a number of implementations for the interface. The actual implementations are registered as keyed services in the container.
What I would like to do is to resolve an instance of every service (hence the IEnumerable) that are registered with a specific keytype (hence the typed registration).
If I use the container directly, it works:
container.ResolveKeyed<IEnumerable<IService>>(MyServiceGroups.Group1);
// This returns the a list of IService implementor objects, that were previously registered with the given key
However, if I use the [KeyFilter] attribute in my constructors to resolve the dependencies, it has no effect and I get the list of all registered services, regardless of the value used at the keyed registrations.
public class MyBigService([KeyFilter(MyServiceGroups.Group1)] services)
{
// here services contains one from every type, not just the ones registered with that particular key
}
What am I doing wrong? Is there any way to make this work? I could probably combine the Func and IEnumerable types and resolve from the container that way manually (since that works), but I'd like to keep this structure.
EDIT
Concrete example with code:
public class SubserviceModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<SubServiceA>().As<ISubService>().Keyed<ISubService>(ServiceType.TypeX);
builder.RegisterType<SubServiceB>().As<ISubService>().Keyed<ISubService>(ServiceType.TypeX);
builder.RegisterType<SubServiceC>().As<ISubService>().Keyed<ISubService>(ServiceType.TypeY);
builder.RegisterType<SubServiceD>().As<ISubService>().Keyed<ISubService>(ServiceType.TypeY);
}
}
public class ServiceModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<Service1>();
builder.RegisterType<Service2>();
}
}
public abstract class ServiceBase
{
public ServiceBase(IEnumerable<ISubService> subServices) {/*...*/}
}
public class Service1
{
public ServiceA([KeyFilter(ServiceGroup.ServiceTypeX)] IEnumerable<ISubService> subServices)
: base(subServices) { /* ... */ }
}
public class Service2
{
public ServiceB([KeyFilter(ServiceGroup.ServiceTypeY)] IEnumerable<ISubService> subServices)
: base(subServices) { /* ... */ }
}
Well, I came up with an answer myself for now. I basically do what I'd expect Autofac would do: go though all the parameters, and use the current resolving context to resolve it. I check the parameter myself for the attribute, and if it's there, I resolve as a keyed service, otherwise, I just resolve. I also created a nice little extension method to hide the added complexity of this registration:
public static class AutofacExtensions
{
public static IRegistrationBuilder<TService, SimpleActivatorData, SingleRegistrationStyle> RegisterModulePageViewModel<TService>(this ContainerBuilder builder) where TService : ServiceBase
{
return builder.Register(ctx => CreateInstance<TService>(ctx));
}
private static TService CreateInstance<TService>(IComponentContext ctx)
{
var ctor = typeof(TService).GetConstructors().Single();
List<object> parameters = new List<object>();
foreach (var param in ctor.GetParameters())
{
var keyAttribute = param.GetCustomAttribute<KeyFilterAttribute>();
if (keyAttribute != null)
{
parameters.Add(ctx.ResolveKeyed(keyAttribute.Key, param.ParameterType));
}
else
{
parameters.Add(ctx.Resolve(param.ParameterType));
}
}
return (TService)ctor.Invoke(parameters.ToArray());
}
}
I have several Get____Factory methods in my application and I'd like to consolidate them with generics, but I'm still adjusting C# and a) am not 100% sure generics are the right way to go and b) am still learning how C# handles generics.
I'll eventually have a dictionary/map of factory interfaces and their classes. Not only do I want to consolidate all of my factories into an easy-access method but I need to allow plugin authors a way to register their own (and have access to them this way).
I started with something like this:
Note: Eventually there will be a dictionary or way to map interfaces types to their implementations - the if/else conditions are ugly and temporary, but simply a way to test.
public T GetFactory<T>() where T : IFactory {
var t = typeof(T);
if (t.Equals(typeof(IRecipeFactory))) {
var factory = new RecipeFactory();
return factory;
}
else if (t.Equals(typeof(IItemFactory))) {
var factory = new ItemFactory();
return factory;
}
else if (t.Equals(typeof(ITileFactory))) {
var factory = new TileFactory();
return factory;
}
}
It fails with Cannot implicitly convert type 'RecipeFactory' to 'T', so this won't work. In the long run I won't have conditionals but will rather lookup the class by its type. However, neither will work until I can find a solution for the cast issue.
Based on other answers, I tried double-casting ((T) (object)) but that errors with InvalidCastException: Cannot cast from source type to destination type..
Either this is a poor architecture or I'm using the generics incorrectly.
Here is solution bit different from S.C.'s solution.
public static class FactoryService
{
private static readonly Dictionary<Type, Func<IFactory>> factories = new Dictionary<Type, Func<IFactory>>()
{
{ typeof(IRecipeFactory), () => new RecipeFactory() },
{ typeof(IItemFactory), () => new ItemFactory() },
{ typeof(ITileFactory), () => new TileFactory() }
};
public static T GetFactory<T>() where T : IFactory
{
T factory = default(T);
Type requestedType = typeof(T);
if (factories.ContainsKey(requestedType))
{
factory = (T)factories[requestedType].Invoke();
}
return factory;
}
}
public interface IFactory { }
public interface IRecipeFactory : IFactory { }
public interface IItemFactory : IFactory { }
public interface ITileFactory : IFactory { }
public class RecipeFactory : IRecipeFactory { }
public class ItemFactory : IItemFactory { }
public class TileFactory : ITileFactory { }
Then you use it like this:
IRecipeFactory rf = FactoryService.GetFactory<IRecipeFactory>();
Let me first say that you are actually looking at is a simple version of an Inversion of Control (IOC) framework. Take a look at Ninject or something similar because it's kernel and binding factory are pretty much exactly what you want. It even allows the attachment of metadata so you can have the same interface resolve to different implementations depending on the circumstances, which is really useful when you have a data layer that might need to pull from either a web data source or a cache data source, for instance. Most IOC frameworks also offer recursive dependency resolution, which means when some instances have constructors that require other dependencies, the same dependency resolution occurs all the way down the chain based on the mappings or default mappings that can be inferred.
Aside from that, to do what you're after yourself, you'll want to make use of Activator.CreateInstance which takes a type and will construct a new instance based on that. You are on the right track with your dictionary mappings. When you tie those two together, you don't need any conditional logic and you don't need to know ahead of time or care about what type is being requested. When you're feeling comfortable you can actually shorten the dependency resolution and instantiation to a single line if you wish.
Here is a fully working sample (from my 30 seconds of testing) that does what you want to to the best of my understanding:
using System;
using System.Collections.Generic;
namespace Generics
{
// create some dummy interfaces and implementations.
// make sure everything inherits from the same type to allow for
// a generic return statement
public interface IFactory
{
void DoStuff();
}
public interface IFactory1 : IFactory { }
public class Factory1 : IFactory1
{
public void DoStuff()
{
Console.WriteLine("Factory1");
}
}
public interface IFactory2 : IFactory { }
public class Factory2 : IFactory2
{
public void DoStuff()
{
Console.WriteLine("Factory2");
}
}
class Program
{
// create our binding mappings
IDictionary<Type, Type> bindings = new Dictionary<Type, Type>()
{
// expose a way for plugins/etc to add to this. that part is trivial.
{typeof(IFactory1), typeof(Factory1) },
{typeof(IFactory2), typeof(Factory2) }
};
// a method to actually resolve bindings based on expected types
public IFactory ResolveBinding<T>() where T : IFactory
{
Type requestedType = typeof(T);
if (requestedType != null && bindings.ContainsKey(requestedType))
{
// use the activator to generically create an instance
return (T) Activator.CreateInstance(bindings[requestedType]);
}
return null;
}
// test it out
static void Main(string[] args)
{
Program demo = new Program();
// test with two interfaces
demo.ResolveBinding<IFactory1>().DoStuff(); // prints out "Factory1"
demo.ResolveBinding<IFactory2>().DoStuff(); // prints out "Factory2"
Console.ReadKey();
}
}
}
You are going to want to cast the object to T on the way out since the method returns T. To do this cast you will have to make factory an IFactory
public T GetFactory<T>() where T : IFactory
{
var t = typeof(T);
if (t.Equals(typeof(IRecipeFactory)))
{
IFactory factory = new RecipeFactory();
return (T)factory;
}
if (t.Equals(typeof(IItemFactory)))
{
IFactory factory = new ItemFactory();
return (T)factory;
}
if (t.Equals(typeof(ITileFactory)))
{
IFactory factory = new TileFactory();
return (T)factory;
}
throw new InvalidOperationException("Type not supported");
}
This blog post describes a nice alternative to the Repository pattern.
https://cuttingedge.it/blogs/steven/pivot/entry.php?id=92
Instead of Repositories the author recommends the use of Commands and Queries. The particular blog post describes the implementation of the Query part in .NET/C#.
There are two interfaces for the query and for the query handler:
public interface IQuery<TResult>
{
}
public interface IQueryHandler<TQuery, TResult> where TQuery : IQuery<TResult>
{
TResult Handle(TQuery query);
}
He also offers an example for each:
public class FindUsersBySearchTextQuery : IQuery<User[]>
{
public string SearchText { get; set; }
public bool IncludeInactiveUsers { get; set; }
}
public class FindUsersBySearchTextQueryHandler
: IQueryHandler<FindUsersBySearchTextQuery, User[]>
{
private readonly NorthwindUnitOfWork db;
public FindUsersBySearchTextQueryHandler(NorthwindUnitOfWork db)
{
this.db = db;
}
public User[] Handle(FindUsersBySearchTextQuery query)
{
return (
from user in this.db.Users
where user.Name.Contains(query.SearchText)
select user)
.ToArray();
}
}
The query handler can be provided as a constructor parameter to a MVC controller.
public class UserController : Controller
{
IQueryHandler<FindUsersBySearchTextQuery, User[]> handler;
public UserController(IQueryHandler<FindUsersBySearchTextQuery, User[]> handler)
{
this.handler = handler;
}
public View SearchUsers(string searchString)
{
var query = new FindUsersBySearchTextQuery
{
SearchText = searchString,
IncludeInactiveUsers = false
};
User[] users = this.handler.Handle(query);
return this.View(users);
}
}
The author uses the dependency injection container Simple Injector to register all IQueryHandler's at once:
container.RegisterManyForOpenGeneric(
typeof(IQueryHandler<,>),
typeof(IQueryHandler<,>).Assembly);
My question is: How can I do this last statement in Unity?
I'm using Unity 3.5.
I'm able to register each QueryHandler manually, like this:
container.RegisterType<IQueryHandler<FindUsersBySearchTextQuery, User[]>,
FindUsersBySearchTextQueryHandler>();
This works fine but I don't want to add a new mapping each time a new QueryHandler comes up. I want to set up all mappings with one convention which includes future QueryHandler's. Unity 3.5 offers a convention based registration workflow but I could not make it work for my case. I tried this but unfortunately it does not generate the mappings in question.
container.RegisterTypes(
AllClasses.FromLoadedAssemblies(),
WithMappings.FromMatchingInterface,
WithName.Default);
If you are going to have many specific implementations of IQueryHandler<,> and not one generic version, then you can't use open generics to register. But you can use reflection to find all implementations and register them each. (This is what RegisterTypes does behind the scenes for you).
You were close with your attempt at the RegisterTypes call in the question, but you used WithMappings.FromMatchingInterface. This will only register classes with their interface that matches by the naming convention of MyClass : IMyClass (prepending an 'I' to the class name). If you instead register with WithMappings.FromAllInterfaces you will get the registrations you are after.
container.RegisterTypes(
AllClasses.FromLoadedAssemblies(),
WithMappings.FromAllInterfaces,
WithName.Default);
If you need to only register those classes, you can filter down the classes to only those that implement the interface you are after...
public static class EnumerableTypeExtensions
{
public static IEnumerable<Type> WhichImplementsInterface<T>
(this IEnumerable<Type> types)
{
return types.WhichImplementsInterface(typeof (T));
}
public static IEnumerable<Type> WhichImplementsInterface
(this IEnumerable<Type> types, Type interfaceType)
{
return types.WhichImplementsInterface(interfaceType.Name);
}
public static IEnumerable<Type> WhichImplementsInterface
(this IEnumerable<Type> types, string interfaceTypeName)
{
return types.Where(t => t.GetInterface(interfaceTypeName) != null);
}
}
Then you can use these filters like this...
container.RegisterTypes(
AllClasses.FromLoadedAssemblies().WhichImplementsInterface(typeof(IQueryHandler<,>)),
WithMappings.FromAllInterfaces,
WithName.Default);
Can Castle Windsor resolve a collection filtered by a string parameter?
interface IViewFactory
{
IView[] GetAllViewsInRegion(string regionName);
}
My application defines regions as groups of IView-derived types. When I display a particular region at runtime, I want to resolve an instance of every IView type within it (a la Prism).
I've tried doing it with the Castle's Typed Factory Facility, ComponentModel Construction Contributors, and Handler Selectors, but I can't figure out how to map multiple types to a string in a way that Castle can access, nor how to extend Castle to check the string when it decides which types to try to resolve and return in the container.
Is selection by string strictly necessary? Would it be possible to instead have all IView implementations in the same "region" implement a dedicated interface that derives from IView? Then you could use WindsorContainer.ResolveAll() (passing your region-specific IView as T) to resolve the implementations for the region in question (or you could use one of the Collection Resolvers to perform constructor injection).
In general, when trying to do things like this with Windsor, I make every effort to use the type system (and Windsor's support thereof) before resorting to string-based solutions.
Update: since we confirmed that selection by string is necessary in this case, the best solution I see is to simply inspect the list of handlers in the kernel that satisfy the IView service, then filter for the implementers where the region (defined via attribute) matches what we want, then resolve those implementers. This feels a bit hackish, but if you're okay with having a direct reference to the container in your IViewFactory implementation, this appears to work fine. Below is a passing test case demonstrating the solution.
[Test]
public void Test()
{
using (var factory = new ViewFactory())
{
var regionOneViews = factory.GetAllViewsInRegion("One");
Assert.That(regionOneViews, Is.Not.Null);
Assert.That(regionOneViews, Has.Length.EqualTo(2));
Assert.That(regionOneViews, Has.Some.TypeOf<RegionOneA>());
Assert.That(regionOneViews, Has.Some.TypeOf<RegionOneB>());
var regionTwoViews = factory.GetAllViewsInRegion("Two");
Assert.That(regionTwoViews, Is.Not.Null);
Assert.That(regionTwoViews, Has.Length.EqualTo(1));
Assert.That(regionTwoViews, Has.Some.TypeOf<RegionTwoA>());
}
}
}
public interface IViewFactory
{
IView[] GetAllViewsInRegion(string regionName);
}
public class ViewFactory : IViewFactory, IDisposable
{
private readonly WindsorContainer _container;
public ViewFactory()
{
_container = new WindsorContainer();
_container.Register(
Component.For<IView>().ImplementedBy<RegionOneA>(),
Component.For<IView>().ImplementedBy<RegionOneB>(),
Component.For<IView>().ImplementedBy<RegionTwoA>()
);
}
public IView[] GetAllViewsInRegion(string regionName)
{
return _container.Kernel.GetHandlers(typeof (IView))
.Where(h => IsInRegion(h.ComponentModel.Implementation, regionName))
.Select(h => _container.Kernel.Resolve(h.ComponentModel.Name, typeof (IView)) as IView)
.ToArray();
}
private bool IsInRegion(Type implementation,
string regionName)
{
var attr =
implementation.GetCustomAttributes(typeof (RegionAttribute), false).SingleOrDefault() as RegionAttribute;
return attr != null && attr.Name == regionName;
}
public void Dispose()
{
_container.Dispose();
}
}
public interface IView {}
[Region("One")]
public class RegionOneA : IView {}
[Region("One")]
public class RegionOneB : IView {}
[Region("Two")]
public class RegionTwoA : IView {}
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class RegionAttribute : Attribute
{
private readonly string _name;
public RegionAttribute(string name)
{
_name = name;
}
public string Name
{
get { return _name; }
}
}