Added default constructor to PropertyDescriptor. This will normally be used to provi...
[castle.git] / Facilities / BatchRegistration / Castle.Facilities.BatchRegistration / ComponentScanner.cs
blobf4c1540e86912aff4e2728f103bdf769e0ee10be
1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
2 //
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
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
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
17 using System;
18 using System.Reflection;
19 using System.Collections;
20 using System.Configuration;
22 using Castle.Core;
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();
66 SortExcludes();
68 InspectTypes(assembly);
70 ProcessIncludes(assembly);
72 return (ComponentDefinition[]) _result.ToArray( typeof(ComponentDefinition) );
75 private void InspectTypes(Assembly assembly)
77 if (_useAttributes)
79 foreach(Type type in assembly.GetExportedTypes())
81 ProcessType(type);
86 private Assembly LoadAssembly()
88 try
90 return Assembly.Load(_assemblyName);
92 catch(Exception ex)
94 String message =
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(
134 def.Key,
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 ) );
144 /// <summary>
145 /// This method always tries to obtain the type
146 /// from the specified assembly.
147 /// </summary>
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);
156 /// <summary>
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
161 /// </summary>
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);
173 else
175 return TypeLoadUtil.GetType(typeName);