1. AMIR BARYLKO
ADVANCED IOC
WINDSOR
CASTLE
DOT NET UG
NOV 2011
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.