1+ using System ;
2+ using System . Collections . Concurrent ;
3+ using System . Collections . Generic ;
4+ using System . Linq ;
5+ using System . Reflection ;
6+ using LiquidProjections . Statistics ;
7+ using Nancy ;
8+ using Nancy . Bootstrapper ;
9+ using Nancy . Configuration ;
10+ using Nancy . Extensions ;
11+ using Nancy . Linker ;
12+ using Nancy . Metadata . Modules ;
13+ using Nancy . Routing ;
14+ using Nancy . Swagger ;
15+ using Nancy . Swagger . Modules ;
16+ using Nancy . Swagger . Services ;
17+ using Nancy . TinyIoc ;
18+
19+ namespace LiquidProjections . Owin
20+ {
21+ internal class CustomNancyBootstrapper : DefaultNancyBootstrapper
22+ {
23+ private readonly ProjectionStats stats ;
24+
25+ public CustomNancyBootstrapper ( ProjectionStats stats )
26+ {
27+ this . stats = stats ;
28+ }
29+
30+ protected override void ApplicationStartup ( TinyIoCContainer container , IPipelines pipelines )
31+ {
32+ base . ApplicationStartup ( container , pipelines ) ;
33+
34+ SwaggerMetadataProvider . SetInfo (
35+ "LiquidProjections" ,
36+ Assembly . GetExecutingAssembly ( ) . GetName ( ) . Version . ToString ( ) ,
37+ "Provides statistics about running projectors"
38+ ) ;
39+ }
40+
41+ #if DEBUG
42+
43+ public override void Configure ( INancyEnvironment environment )
44+ {
45+ environment . Tracing ( enabled : false , displayErrorTraces : true ) ;
46+ base . Configure ( environment ) ;
47+ }
48+ #endif
49+
50+ protected override IAssemblyCatalog AssemblyCatalog => new StaticAssemblyCatalog ( ) ;
51+
52+ protected override ITypeCatalog TypeCatalog => new InternalTypeCatalog ( AssemblyCatalog ) ;
53+
54+ protected override void ConfigureApplicationContainer ( TinyIoCContainer container )
55+ {
56+ container . Register < IResourceLinker > ( ( x , overloads ) =>
57+ new ResourceLinker ( x . Resolve < IRouteCacheProvider > ( ) ,
58+ x . Resolve < IRouteSegmentExtractor > ( ) , x . Resolve < IUriFilter > ( ) ) ) ;
59+
60+ container . Register < IRegistrations , Registration > ( "LinkerRegistrations" ) ;
61+ container . Register < IRegistrations , SwaggerRegistrations > ( "SwaggerRegistrations" ) ;
62+ container . Register ( stats ) ;
63+ }
64+
65+ protected override IEnumerable < ModuleRegistration > Modules =>
66+ new [ ]
67+ {
68+ new ModuleRegistration ( typeof ( SwaggerModule ) ) ,
69+ new ModuleRegistration ( typeof ( StatisticsModule ) )
70+ } ;
71+ }
72+
73+ internal class StaticAssemblyCatalog : IAssemblyCatalog
74+ {
75+ public IReadOnlyCollection < Assembly > GetAssemblies ( )
76+ {
77+ return new [ ]
78+ {
79+ typeof ( MetadataModuleRegistrations ) . Assembly ,
80+ typeof ( CustomNancyBootstrapper ) . Assembly ,
81+ typeof ( DefaultNancyBootstrapper ) . Assembly
82+ } . Distinct ( ) . ToArray ( ) ;
83+ }
84+ }
85+
86+ /// <summary>
87+ /// Implementation of the <see cref="T:Nancy.ITypeCatalog" /> interface that will find internal types as well.
88+ /// </summary>
89+ internal class InternalTypeCatalog : ITypeCatalog
90+ {
91+ private readonly IAssemblyCatalog assemblyCatalog ;
92+ private readonly ConcurrentDictionary < Type , IReadOnlyCollection < Type > > cache ;
93+
94+ /// <summary>
95+ /// Initializes a new instance of the <see cref="T:Nancy.DefaultTypeCatalog" /> class.
96+ /// </summary>
97+ /// <param name="assemblyCatalog">An <see cref="T:Nancy.IAssemblyCatalog" /> instanced, used to get the assemblies that types should be resolved from.</param>
98+ public InternalTypeCatalog ( IAssemblyCatalog assemblyCatalog )
99+ {
100+ this . assemblyCatalog = assemblyCatalog ;
101+ cache = new ConcurrentDictionary < Type , IReadOnlyCollection < Type > > ( ) ;
102+ }
103+
104+ /// <summary>
105+ /// Gets all types that are assignable to the provided <paramref name="type" />.
106+ /// </summary>
107+ /// <param name="type">The <see cref="T:System.Type" /> that returned types should be assignable to.</param>
108+ /// <param name="strategy">A <see cref="T:Nancy.TypeResolveStrategy" /> that should be used when retrieving types.</param>
109+ /// <returns>An <see cref="T:System.Collections.Generic.IReadOnlyCollection`1" /> of <see cref="T:System.Type" /> instances.</returns>
110+ public IReadOnlyCollection < Type > GetTypesAssignableTo ( Type type , TypeResolveStrategy strategy )
111+ {
112+ return cache . GetOrAdd ( type , t => GetTypesAssignableTo ( type ) )
113+ . Where ( strategy . Invoke ) . ToArray ( ) ;
114+ }
115+
116+ private IReadOnlyCollection < Type > GetTypesAssignableTo ( Type type )
117+ {
118+ return assemblyCatalog . GetAssemblies ( )
119+ . SelectMany ( assembly => assembly . SafeGetTypes ( ) )
120+ . Where ( type . IsAssignableFrom )
121+ . Where ( t => ! t . GetTypeInfo ( ) . IsAbstract ) . ToArray ( ) ;
122+ }
123+ }
124+ }
0 commit comments