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
.MonoRail
.ActiveRecordSupport
18 using System
.Reflection
;
20 using Castle
.MonoRail
.Framework
;
23 /// Mark a parameter with this attribute to instruct the <see cref="SmartDispatcherController" />
24 /// to load an <c>ActiveRecord</c> instance of the parameter type, using the request parameter
25 /// as the identifier.
28 /// The <see cref="ARFetchAttribute"/> only loads an instance
29 /// based on the primary key value obtained from <see cref="IRailsEngineContext.Params"/>
30 /// <para>For example:</para>
32 /// public class CustomerController : ARSmartDispatcherController
34 /// public void UpdateCustomerLocation([ARFetch("customer.id")] Customer customer, [ARFetch("location.id")] Location location)
36 /// customer.Location = location;
39 /// RedirectToAction("index");
43 /// The code above assumes that you have the fields
44 /// <c>customer.id</c> and <c>location.id</c> on the form being
47 [AttributeUsage(AttributeTargets
.Parameter
), Serializable
]
48 public class ARFetchAttribute
: Attribute
, IParameterBinder
50 private String requestParameterName
;
51 private bool create
, required
;
55 /// Constructs an <see cref="ARFetchAttribute"/>
56 /// specifying the parameter name and the create and require behavior
58 /// <param name="requestParameterName">The parameter name to be read from the request</param>
59 /// <param name="create"><c>true</c> if you want an instance even when the record is not found</param>
60 /// <param name="required"><c>true</c> if you want an exception if the record is not found</param>
61 public ARFetchAttribute(String requestParameterName
, bool create
, bool required
) : base()
63 this.requestParameterName
= requestParameterName
;
65 this.required
= required
;
69 /// Constructs an <see cref="ARFetchAttribute"/> using the
70 /// parameter name as the <see cref="ARFetchAttribute.RequestParameterName"/>
72 public ARFetchAttribute() : this(null, false, false)
77 /// Constructs an <see cref="ARFetchAttribute"/> specifing the
79 /// <seealso cref="ARFetchAttribute.RequestParameterName"/>
81 public ARFetchAttribute(String requestParameterName
) : this(requestParameterName
, false, false)
86 /// Constructs an <see cref="ARFetchAttribute"/> using the
87 /// parameter name as the <see cref="ARFetchAttribute.RequestParameterName"/>
88 /// and the create and require behavior
90 /// <param name="create"><c>true</c> if you want an instance even when the record is not found</param>
91 /// <param name="require"><c>true</c> if you want an exception if the record is not found</param>
92 public ARFetchAttribute(bool create
, bool require
) : this(null, create
, require
)
97 /// The parameter name to be read from the request. The parameter value will
98 /// be used as the primary key value to load the target object instance.
100 public String RequestParameterName
102 get { return requestParameterName; }
103 set { requestParameterName = value; }
107 /// When set to <c>true</c> an instance of
108 /// the target type will be created if the record
109 /// is not found. The default is <c>false</c>.
113 get { return create; }
114 set { create = value; }
118 /// When set to <c>true</c>, an exception will be thrown
119 /// if the record specified is not found. The default is <c>false</c>.
123 get { return required; }
124 set { required = value; }
128 /// Comma-separated list of lazy associations to eager-fetch, when loading the ActiveRecord object.
132 get { return eager; }
133 set { eager = value; }
136 public virtual int CalculateParamPoints(SmartDispatcherController controller
, ParameterInfo parameterInfo
)
138 String paramName
= RequestParameterName
!= null ? RequestParameterName
: parameterInfo
.Name
;
140 return controller
.Request
.Params
.Get(paramName
) != null ? 10 : 0;
143 public virtual object Bind(SmartDispatcherController controller
, ParameterInfo parameterInfo
)
145 ARFetcher fetcher
= new ARFetcher(controller
.Binder
.Converter
);
147 return fetcher
.FetchActiveRecord(parameterInfo
, this, controller
.Request
);