1 // Copyright 2004-2008 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
.MonoRail
.Framework
.Services
18 using System
.Collections
;
21 /// Centralizes the registration and lookup of ViewComponents
23 public class DefaultViewComponentRegistry
: IViewComponentRegistry
25 private readonly Hashtable name2Type
= new Hashtable(StringComparer
.InvariantCultureIgnoreCase
);
27 #region IViewComponentRegistry
30 /// Adds the view component.
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
);
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
;
61 /// Gets the view component.
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
];
83 /// Normalizes the name.
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";
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)
112 return (ViewComponentDetailsAttribute
)attributes
[0];