This document provides an overview of advanced topics in Inversion of Control (IoC) containers, including registering components, generics, dependencies, lifecycles, naming, installers, conventions, and Castle DynamicProxy for aspect-oriented programming. It discusses facilities like startable components, typed factories, and interceptors. The document is presented by Amir Barylko of MavenThought Inc. and provides code examples for many of the concepts discussed.
1. AMIR BARYLKO
ADVANCED IOC
WINDSOR
CASTLE
Amir Barylko - Advanced IoC MavenThought Inc.
2. FIRST STEPS
Why IoC containers
Registering Components
LifeStyles
Naming
Amir Barylko - Advanced IoC MavenThought Inc.
3. WHY USE IOC
• Manage creation and disposing objects
• Avoid hardcoding dependencies
• Dependency injection
• Dynamically configure instances
• Additional features
Amir Barylko - Advanced IoC MavenThought Inc.
4. REGISTRATION
• In order to resolve instances, we need to register them
Container.Register(
// Movie class registered
Component.For<Movie>(),
// IMovie implementation registered
Component.For<IMovie>().ImplementedBy<Movie>()
);
Amir Barylko - Advanced IoC MavenThought Inc.
5. GENERICS
•What If I want to register a generic class?
container.Register(
Component
.For(typeof(IRepository<>)
.ImplementedBy(typeof(NHRepository<>)
);
Amir Barylko - Advanced IoC MavenThought Inc.
6. DEPENDENCIES
Component
.For<IMovieFactory>()
.ImplementedBy<NHMovieFactory>(),
Component
.For<IMovieRepository>()
.ImplementedBy<SimpleMovieRepository>()
public class SimpleMovieRepository : IMovieRepository
{
public SimpleMovieRepository(IMovieFactory factory)
{
_factory = factory;
}
}
Amir Barylko - Advanced IoC MavenThought Inc.
7. LIFESTYLE
• Singleton vs Transient
• Which one is the default? And for other IoC tools?
container.Register(
Component.For<IMovie>()
.ImplementedBy<Movie>()
.LifeStyle.Transient
);
Amir Barylko - Advanced IoC MavenThought Inc.
8. RELEASING
• Do I need to release the instances?
Amir Barylko - Advanced IoC MavenThought Inc.
9. NAMING
• Who’s the one resolved?
container.Register(
Component
.For<IMovie>()
.ImplementedBy<Movie>(),
Component
.For<IMovie>()
.ImplementedBy<RottenTomatoesMovie>()
);
Amir Barylko - Advanced IoC MavenThought Inc.
10. NAMING II
• Assign unique names to registration
container.Register(
...
Component
.For<IMovie>()
.ImplementedBy<RottenTomatoesMovie>()
.Named("RT")
);
container.Resolve<IMovie>("RT");
Amir Barylko - Advanced IoC MavenThought Inc.
11. JOGGING
Installers
Using Conventions
Depend On
Amir Barylko - Advanced IoC MavenThought Inc.
12. INSTALLERS
• Where do we put the registration code?
• Encapsulation
• Partition logic
• Easy to maintain
Amir Barylko - Advanced IoC MavenThought Inc.
13. INSTALLER EXAMPLE
container.Install(
new EntitiesInstaller(),
new RepositoriesInstaller(),
// or use FromAssembly!
FromAssembly.This(),
FromAssembly.Named("MavenThought...."),
FromAssembly.Containing<ServicesInstaller>(),
FromAssembly.InDirectory(new AssemblyFilter("...")),
FromAssembly.Instance(this.GetPluginAssembly())
);
Amir Barylko - Advanced IoC MavenThought Inc.
14. XML CONFIG
var res = new AssemblyResource("assembly://.../
ioc.xml")
container.Install(
Configuration.FromAppConfig(),
Configuration.FromXmlFile("ioc.xml"),
Configuration.FromXml(res)
);
Amir Barylko - Advanced IoC MavenThought Inc.
15. CONVENTIONS
Classes
.FromAssemblyContaining<IMovie>()
.BasedOn<IMovie>()
.WithService.Base() // Register the service
.LifestyleTransient() // Transient lifestyle
Amir Barylko - Advanced IoC MavenThought Inc.
16. CONFIGURE COMPONENTS
Classes
.FromAssemblyContaining<IMovie>()
.BasedOn<IMovie>()
.LifestyleTransient()
// Using naming to identify instances
.Configure(r => r.Named(r.Implementation.Name))
Amir Barylko - Advanced IoC MavenThought Inc.
17. DEPENDS ON
var rtKey = @"the key goes here";
container.Register(
Component
.For<IMovieFactory>()
.ImplementedBy<RottenTomatoesFactory>()
.DependsOn(Property.ForKey("apiKey").Eq(rtKey))
);
.DependsOn(new { apiKey = rtKey } ) // using anonymous class
.DependsOn(
new Dictionary<string,string>{
{"APIKey", twitterApiKey}}) // using dictionary
Amir Barylko - Advanced IoC MavenThought Inc.
18. SERVICE OVERRIDE
container.Register(
Component
.For<IMovieFactory>()
.ImplementedBy<IMDBMovieFactory>()
.Named(“imdbFactory”)
Component
.For<IMovieRepository>()
.ImplementedBy<SimpleMovieRepository>()
.DependsOn(Dependency.OnComponent("factory", "imdbFactory"))
);
Amir Barylko - Advanced IoC MavenThought Inc.
19. RUN FOREST! RUN!
Startable Facility
Interface Based Factories
Castle AOP
Amir Barylko - Advanced IoC MavenThought Inc.
20. STARTABLE FACILITY
• Allows objects to be started when they are created
• And stopped when they are released
• Start and stop methods have to be public, void and no
parameters
• You can use it with POCO objects specifying which method
to use to start and stop
Amir Barylko - Advanced IoC MavenThought Inc.
21. STARTABLE CLASS
public interface IStartable
{
void Start();
void Stop();
}
var container = new WindsorContainer()
.AddFacility<StartableFacility>()
.Register(
Component
.For<IThing>()
.ImplementedBy<StartableThing>()
);
Amir Barylko - Advanced IoC MavenThought Inc.
22. FACTORIES
• Common pattern to create objects
• But the IoC is some kind of factory too...
• Each factory should use the IoC then....
• Unless we use Windsor!!!!
Amir Barylko - Advanced IoC MavenThought Inc.
23. TYPED FACTORIES
• Create a factory based on an interface
• Methods that return values are Resolve methods
• Methods that are void are Release methods
• Collection methods resolve to multiple components
Amir Barylko - Advanced IoC MavenThought Inc.
24. REGISTER FACTORY
Kernel.AddFacility<TypedFactoryFacility>();
Register(
Component
.For<IMovie>()
.ImplementedBy<NHMovie>()
.LifeStyle.Transient,
Component.For<IMovieFactory>().AsFactory()
);
Amir Barylko - Advanced IoC MavenThought Inc.
25. CASTLE AOP
• Inject code around methods
• Cross cutting concerns
• Avoid mixing modelling and usage
• Avoid littering the code with new requirements
Amir Barylko - Advanced IoC MavenThought Inc.
26. INTERCEPTORS
Register(
Component
.For<LoggingInterceptor>()
.LifeStyle.Transient,
Component
.For<IMovie>()
.ImplementedBy<NHMovie>()
.Interceptors(InterceptorReference
.ForType<LoggingInterceptor>()).Anywhere
.LifeStyle.Transient
);
Amir Barylko - Advanced IoC MavenThought Inc.
27. LOGGING
public class LoggingInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Debug.WriteLine("Before execution");
invocation.Proceed();
Debug.WriteLine("After execution");
}
}
Amir Barylko - Advanced IoC MavenThought Inc.
28. NOTIFY PROPERTY CHANGED
Register(
Component
.For<NotifyPropertyChangedInterceptor>()
.LifeStyle.Transient,
Component
.For<IMovieViewModel>()
.ImplementedBy<MovieViewModel>()
.Interceptors(InterceptorReference
.ForType<NotifyPropertyChangedInterceptor>())
.Anywhere
.LifeStyle.Transient
);
Amir Barylko - Advanced IoC MavenThought Inc.