1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.Facilities
.BatchRegistration
18 using System
.Reflection
;
19 using System
.Collections
;
20 using System
.Configuration
;
25 public sealed class ComponentScanner
27 private bool _useAttributes
;
28 private String _assemblyName
;
29 private ArrayList _includes
;
30 private ArrayList _excludes
;
31 private ArrayList _result
;
33 public ComponentScanner(String assemblyName
)
35 _includes
= new ArrayList();
36 _excludes
= new ArrayList();
37 _result
= new ArrayList();
38 _assemblyName
= assemblyName
;
41 public bool UseAttributes
43 get { return _useAttributes; }
44 set { _useAttributes = value; }
47 public void AddInclude(String key
, String service
, String className
)
49 if (key
== null) throw new ArgumentNullException("key");
50 if (className
== null) throw new ArgumentNullException("className");
52 _includes
.Add(new ComponentDefinition(key
, service
, className
));
55 public void AddExclude(String className
)
57 if (className
== null) throw new ArgumentNullException("className");
59 _excludes
.Add(className
);
62 public ComponentDefinition
[] Process()
64 Assembly assembly
= LoadAssembly();
68 InspectTypes(assembly
);
70 ProcessIncludes(assembly
);
72 return (ComponentDefinition
[]) _result
.ToArray( typeof(ComponentDefinition
) );
75 private void InspectTypes(Assembly assembly
)
79 foreach(Type type
in assembly
.GetExportedTypes())
86 private Assembly
LoadAssembly()
90 return Assembly
.Load(_assemblyName
);
95 String
.Format("Could not load the specified assembly {0}", _assemblyName
);
97 throw new ConfigurationErrorsException(message
, ex
);
101 private void ProcessIncludes(Assembly assembly
)
103 foreach(ComponentDefinition def
in _includes
)
105 if (_excludes
.BinarySearch( def
.ClassName
) == -1)
107 AddToResult( assembly
, def
);
112 private void SortExcludes()
114 _excludes
.Sort( CaseInsensitiveComparer
.Default
);
117 private void ProcessType(Type type
)
119 if (type
.IsDefined( typeof(CastleComponentAttribute
), false ))
121 if (_excludes
.BinarySearch( type
.FullName
) == -1)
123 CastleComponentAttribute attribute
= (CastleComponentAttribute
)
124 type
.GetCustomAttributes( typeof(CastleComponentAttribute
), false )[0];
126 AddToResult( type
, attribute
);
131 private void AddToResult(Assembly assembly
, ComponentDefinition def
)
133 _result
.Add( new ComponentDefinition(
135 ObtainType(assembly
, def
.Service
),
136 InferType(assembly
, def
.ClassName
) ) );
139 private void AddToResult(Type type
, CastleComponentAttribute attribute
)
141 _result
.Add( new ComponentDefinition( attribute
.Key
, attribute
.Service
, type
) );
145 /// This method always tries to obtain the type
146 /// from the specified assembly.
148 /// <param name="typeName"></param>
149 /// <param name="assembly"></param>
150 /// <returns></returns>
151 private Type
InferType(Assembly assembly
, String typeName
)
153 return TypeLoadUtil
.GetType(assembly
, typeName
);
157 /// Obtains the <c>Type</c> by checking if the
158 /// <c>typeName</c> is possible a full type name, or
159 /// just an namespace.typename and for the later case,
160 /// it tries to load the type from the specified assembly
162 /// <param name="assembly"></param>
163 /// <param name="typeName"></param>
164 /// <returns></returns>
165 private Type
ObtainType(Assembly assembly
, String typeName
)
167 if (typeName
== null) return null;
169 if (typeName
.IndexOf(',') == -1)
171 return InferType(assembly
, typeName
);
175 return TypeLoadUtil
.GetType(typeName
);