Fixing an issue with output parameters that are of type IntPtr
[castle.git] / MonoRail / Castle.MonoRail.Framework / Services / DefaultViewComponentRegistry.cs
blob2ca37fba9fc3e29bb7d4dbb775f9c4b03e327738
1 // Copyright 2004-2008 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.MonoRail.Framework.Services
17 using System;
18 using System.Collections;
20 /// <summary>
21 /// Centralizes the registration and lookup of ViewComponents
22 /// </summary>
23 public class DefaultViewComponentRegistry : IViewComponentRegistry
25 private readonly Hashtable name2Type = new Hashtable(StringComparer.InvariantCultureIgnoreCase);
27 #region IViewComponentRegistry
29 /// <summary>
30 /// Adds the view component.
31 /// </summary>
32 /// <param name="name">The name that can be used from the view template.</param>
33 /// <param name="type">The type.</param>
34 public void AddViewComponent(string name, Type type)
36 ViewComponentDetailsAttribute details = GetDetails(type);
38 if (details != null)
40 name = details.Name;
43 name = NormalizeName(name);
45 if (name2Type.Contains(name))
47 throw new MonoRailException(String.Format("ViewComponent '{0}' seems to be registered already. " +
48 "This is due to it being registered more than once or a name clash", name));
51 if (!typeof(ViewComponent).IsAssignableFrom(type))
53 throw new MonoRailException(String.Format("You tried to register '{0}' as a view component but it " +
54 "doesn't seem the extend the ViewComponent abstract class: {1}", name, type.FullName));
57 name2Type[name] = type;
60 /// <summary>
61 /// Gets the view component.
62 /// </summary>
63 /// <param name="name">The name.</param>
64 /// <returns></returns>
65 public Type GetViewComponent(string name)
67 name = NormalizeName(name);
69 if (!name2Type.Contains(name))
71 throw new MonoRailException(String.Format("ViewComponent '{0}' could not be found. Was it registered? " +
72 "If you have enabled Windsor Integration, then it's likely that you have forgot to register the " +
73 "view component as a Windsor component. If you are sure you did it, then make sure the name used " +
74 "is the component id or the key passed to ViewComponentDetailsAttribute", name));
77 return (Type) name2Type[name];
80 #endregion
82 /// <summary>
83 /// Normalizes the name.
84 /// </summary>
85 /// <param name="name">The name.</param>
86 /// <returns></returns>
87 private static string NormalizeName(string name)
89 if (!name.EndsWith("Component", StringComparison.InvariantCultureIgnoreCase))
91 return name + "Component";
93 return name;
96 /// <summary>
97 /// Gets the details.
98 /// </summary>
99 /// <param name="type">The type.</param>
100 /// <returns></returns>
101 private static ViewComponentDetailsAttribute GetDetails(Type type)
103 // TODO: Add cache here, GetCustomAttributes is a lengthy call.
105 object[] attributes = type.GetCustomAttributes(typeof(ViewComponentDetailsAttribute), false);
107 if (attributes.Length == 0)
109 return null;
112 return (ViewComponentDetailsAttribute)attributes[0];