1. Trang chủ
  2. » Công Nghệ Thông Tin

Expert VB 2005 Business Objects Second Edition phần 4 docx

69 328 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 69
Dung lượng 703,04 KB

Nội dung

Next If result Is Nothing Then Throw End If End Try End If Return result End Function Let’s walk through the key parts of the process. First, assuming parameters were passed in for the method, the parameter types are put into a list: ' put all param types into an array of Type Dim paramsAllNothing As Boolean = True Dim types As New List(Of Type) For Each item As Object In parameters If item Is Nothing Then types.Add(GetType(Object)) Else types.Add(item.GetType) paramsAllNothing = False End If Next The r eason for doing this is twofold. F irst, if there is at least one parameter that is not Nothing, then this list is needed for a call to reflection to get the matching method. Second, the loop deter- mines whether there actually are any non- Nothing parameters. If not, the search for a matching method can only by done by parameter count, not data type. ■Note In the general case, this could be problematic, because a Nothing value along with some non-Nothing values could result in an ambiguous match. For the purposes of the data portal, however, this is not an issue because the parameters involved are very clearly defined. If all the parameter values are Nothing, then the search is done based on parameter count rather than parameter type. This is complicated, however, by the fact that preference is given to methods lower on the inheritance hierarchy. In other words, if both a base class and subclass have methods of the same name and number of parameters, preference is given to the subclass. T o accomplish this, the code loops through the specific class types, starting with the outer- most class and working up through the inheritance chain—ultimately to System.Object: Dim currentType As Type = objectType Do Dim info As MethodInfo = _ currentType.GetMethod(method, oneLevelFlags) If info IsNot Nothing Then If info.GetParameters.Length = parameters.Length Then ' got a match so use it result = info Exit Do End If End If currentType = currentType.BaseType Loop Until currentType Is Nothing CHAPTER 4 ■ DATA ACCESS AND SECURITY184 6315_c04_final.qxd 4/13/06 12:33 PM Page 184 As soon as a match is found, the loop is terminated and the result is used. The other case occurs when at least one parameter is not Nothing. In such a case, reflection can be used in a simpler manner to locate a method with matching parameter types: ' at least one param has a real value ' so search for a strongly typed match result = objectType.GetMethod(method, flags, Nothing, _ CallingConventions.Any, types.ToArray, Nothing) One way or the other, the result is typically a MethodInfo object for the correct method. How- ever, it is possible that no match was found. In that case, as in the case in which no parameters were passed at all, a search is done based purely on the method’s name: result = objectType.GetMethod(method, flags) Finally, it is possible for this check to find multiple matches—an ambiguous result. When that happens, an exception is thrown. In such a case, as a last-ditch effort, all methods on the business class are scanned to see if there’s a match based on method name and parameter count: Dim methods() As MethodInfo = objectType.GetMethods For Each m As MethodInfo In methods If m.Name = method AndAlso _ m.GetParameters.Length = parameters.Length Then result = m Exit For End If Next If even that fails, then the AmbiguousMatchException is thrown so that the business developer knows that something is seriously wrong with the data access methods in their business class. The end result of GetMethod() is a MethodInfo object describing the method on the business class. This MethodInfo object is used by other methods in MethodCaller and in other data portal code. CallMethod The Csla.Server.SimpleDataPortal object (discussed later in the chapter) will ultimately invoke methods on business objects based on the MethodInfo object returned from GetMethod(). To sup- port this, MethodCaller implements two different CallMethod() overloads: Public Function CallMethod(ByVal obj As Object, _ ByVal method As String, ByVal ParamArray parameters() As Object) As Object Dim info As MethodInfo = _ GetMethod(obj.GetType, method, parameters) If info Is Nothing Then Throw New NotImplementedException( _ method & " " & My.Resources.MethodNotImplemented) End If Return CallMethod(obj, info, parameters) End Function Public Function CallMethod(ByVal obj As Object, _ ByVal info As MethodInfo, ByVal ParamArray parameters() As Object) _ As Object CHAPTER 4 ■ DATA ACCESS AND SECURITY 185 6315_c04_final.qxd 4/13/06 12:33 PM Page 185 ' call a Public method on the object Dim result As Object Try result = info.Invoke(obj, parameters) Catch e As Exception Throw New CallMethodException( _ info.Name & " " & My.Resources.MethodCallFailed, _ e.InnerException) End Try Return result End Function The first version accepts the method name as a String value, while the second accepts a MethodInfo object. In the first case, GetMethod() is called to retrieve a matching MethodInfo object. If one isn’t found, an exception is thrown; otherwise, the second version of CallMethod() is invoked. The second version of CallMethod() actually invokes the method by using the MethodInfo object. The interesting bit here is the way exceptions are handled. Since reflection is being used to invoke the business method, any exceptions that occur in the business code end up being wrapped within a reflection exception. To business developers, the exception from reflection isn’t very useful. They want the actual exception that occurred within their business method. To resolve this, when an exception is thrown as the business method is invoked, it is caught, and the InnerException of the reflection exception is wrapped within a new Csla.Server.CallMethodException. Effectively, the reflection exception is stripped off and discarded, leaving only the original exception thrown within the business code. That exception is then wrapped within a CSLA .NET exception so the name of the failed business method can be returned as well. CallMethodIfImplemented The CallMethodIfImplemented() method is similar to the CallMethod() methods mentioned previ- ously, but it doesn’t throw an exception if the method doesn’t exist on the business class. Public Function CallMethodIfImplemented(ByVal obj As Object, _ ByVal method As String, ByVal ParamArray parameters() As Object) As Object Dim info As MethodInfo = _ GetMethod(obj.GetType, method, parameters) If info IsNot Nothing Then Return CallMethod(obj, info, parameters) Else Return Nothing End If End Function This is the same basic code as the first CallMethod() implementation, except that it doesn’t thr o w an ex ception if the method isn ’t found. Instead, it simply returns a value of Nothing. CallMethodIfImplemented() is used b y Csla.Server.SimpleDataPortal to inv oke optional methods on the business class—methods that should be invoked if implemented by the business developer, but which shouldn’t cause failure if they aren’t implemented at all. An example is DataPortal_OnDataPortalInvoke(), which is purely optional, but should be called if it has been implemented b y the business developer. CHAPTER 4 ■ DATA ACCESS AND SECURITY186 6315_c04_final.qxd 4/13/06 12:33 PM Page 186 GetObjectType The final method in MethodCaller is used by both Csla.DataPortal and Csla.Server.DataPortal to determine the type of business object involved in the data portal request. It uses the criteria object supplied by the factory method in the business class to find the type of the business object itself. This method supports the two options discussed earlier: where the criteria class is nested within the business class and where the criteria object inherits from Csla.CriteriaBase: Public Function GetObjectType(ByVal criteria As Object) As Type If criteria.GetType.IsSubclassOf(GetType(CriteriaBase)) Then ' get the type of the actual business object ' from CriteriaBase Return CType(criteria, CriteriaBase).ObjectType Else ' get the type of the actual business object ' based on the nested class scheme in the book Return criteria.GetType.DeclaringType End If End Function If the criteria object is a subclass of Csla.CriteriaBase, then the code simply casts the object to type CriteriaBase and retrieves the business object type by calling the ObjectType property. With a nested criteria class, the code gets the type of the criteria object and then returns the DeclaringType value from the Type object. The DeclaringType property returns the type of the class within which the criteria class is nested. Csla.Server.CallMethodException The MethodCaller class throws a custom Csla.Server.CallMethodException in the case that an exception occurs while calling a method on the business object. The purpose behind throwing this exception is to supply the name of the business method that generated the exception, and to provide the original exception details as an InnerException. More importantly, it preserves the stack trace from the original exception. The original stack trace shows the details about where the exception occurred, and is very useful for debugging. With- out a bit of extra work, this information is lost as the method call comes back through reflection. R emember that MethodCaller.CallMethod() uses r eflection to inv oke the business method. When an exception occurs in the business method, a reflection exception is thrown—with the origi- nal business exception nested inside. CallMethod() strips off the reflection exception and provides the original business exception as a parameter during the creation of the CallMethodException object. I n the constr uctor of CallMethodException, the stack tr ace details fr om that or iginal ex cep- tion ar e stor ed for later use: Public Sub New(ByVal message As String, ByVal ex As Exception) MyBase.New(message, ex) mInnerStackTrace = ex.StackTrace End Sub Then in the StackTrace pr oper ty of CallMethodException, the stack tr ace for the CallMethodException itself is combined with the stack trace from the original exception: CHAPTER 4 ■ DATA ACCESS AND SECURITY 187 6315_c04_final.qxd 4/13/06 12:33 PM Page 187 Public Overrides ReadOnly Property StackTrace() As String Get Return String.Format("{0}{1}{2}", _ mInnerStackTrace, vbCrLf, MyBase.StackTrace) End Get End Property T he result is that the complete stack trace is available—showing the flow from the original exception all the way back to the UI in most cases. Csla.RunLocalAttribute Class The data portal routes client calls to the server based on the client application’s configuration set- tings in its config file. If the configuration is set to use an actual application server, the client call is sent across the network using the channel adapter pattern. However, there are cases in which the business developer knows that there’s no need to send the call across the network—even if the application is configured that way. The most common example of this is in the creation of new business objects. The DataPortal.Create() method is called to create a new object, and it in turn triggers a call to the business object ’s DataPortal_Create() method, wher e the object can load itself with default values from the database. But what if an object doesn’t need to load defaults from the database? In that case, there’s no reason to go across the network at all, and it would be nice to short-circuit the call so that particular object’s DataPortal_Create() would run on the client. This is the purpose behind the RunLocalAttribute. A business developer can mark a data access method with this attribute to tell Csla.DataPortal to force the call to run on the client, regardless of how the application is configured in general. Such a business method would look like this: <RunLocal()> _ Private Sub DataPortal_Create(ByVal criteria As Criteria) ' set default values here End Sub The attribute class itself is quite straightforward: <AttributeUsage(AttributeTargets.Method)> _ Public NotInheritable Class RunLocalAttribute Inherits Attribute End Class As with all custom attributes, it inherits from System.Attribute. The <AttributeUsage()> attribute is used to restrict this attribute so it can only be applied to methods—not classes, properties, etc. Csla.D ataPor talE ventArgs Class The Csla.DataPortal class will raise a couple events that can be handled by the business logic or UI code on the client. These events are raised immediately before and after the data portal calls the ser ver. A DataPortalEventArgs object is pr ovided as a parameter to these events. This object includes information of value when handling the event: CHAPTER 4 ■ DATA ACCESS AND SECURITY188 6315_c04_final.qxd 4/13/06 12:33 PM Page 188 Public Class DataPortalEventArgs Inherits EventArgs Private mDataPortalContext As Server.DataPortalContext Public ReadOnly Property DataPortalContext() As Server.DataPortalContext Get Return mDataPortalContext End Get End Property Public Sub New(ByVal dataPortalContext As Server.DataPortalContext) mDataPortalContext = dataPortalContext End Sub End Class The DataPortalContext property returns the Csla.Server.DataPortalContext object that is passed to the server as part of the client message. The DataPortalContext class will be implemented later in the chapter, but it includes the user’s Principal object (if using custom authentication), the client’s culture information, and the ClientContext and GlobalContext collections. This information can be used by code handling the event to better understand all the informa- tion being passed to the server as part of the client message. Csla.DataPortal Class The primary entry point for the entire data portal infrastructure is the Csla.DataPortal class. Business developers use the methods on this class to trigger all the data portal behaviors. This class is involved in both the channel adapter implementation and in handling context information. This section will focus on the channel adapter code in the class, while the context-handling code will be discussed later in the chapter. The Csla.DataPortal class exposes five primary methods, described in Table 4-11, that can be called by business logic. Table 4-11. Methods Exposed by the Client-Side DataPortal Method Description Create() Calls Csla.Server.DataPortal, which then invokes the DataPortal_Create() method Fetch() C alls Csla.Server.DataPortal, which then inv okes the DataPortal_Fetch() method Update() C alls Csla.Server.DataPortal, which then inv okes the DataPortal_Insert(), DataPortal_Update(), or DataPortal_DeleteSelf() methods , as appropriate Delete() Calls Csla.Server.DataPortal, which then invokes the DataPortal_Delete() method Execute() Calls Csla.Server.DataPortal, which then invokes the DataPortal_Execute() method The class also raises two events that the business developer or UI developer can handle. The DataPortalInvoke event is raised before the server is called, and the DataPortalInvokeComplete event is raised after the call the to the server has returned. B ehind the scenes, each DataPortal method deter mines the network protocol to be used when contacting the server in order to delegate the call to Csla.Server.DataPortal. Of course, Csla. Server.DataPortal ultimately delegates the call to Csla.Server.SimpleDataPortal and then to the business object on the server. CHAPTER 4 ■ DATA ACCESS AND SECURITY 189 6315_c04_final.qxd 4/13/06 12:33 PM Page 189 The Csla.DataPortal class is designed to expose Shared methods. As such, it is a Module: P ublic Module DataPortal End Module This ensures that an instance of Csla.DataPortal won’t be created. Data Portal Events The class defines two events, DataPortalInvoke and DataPortalInvokeComplete: Public Event DataPortalInvoke As Action(Of DataPortalEventArgs) Public Event DataPortalInvokeComplete As Action(Of DataPortalEventArgs) Private Sub OnDataPortalInvoke(ByVal e As DataPortalEventArgs) RaiseEvent DataPortalInvoke(e) End Sub Private Sub OnDataPortalInvokeComplete(ByVal e As DataPortalEventArgs) RaiseEvent DataPortalInvokeComplete(e) End Sub These follow the standard approach by providing helper methods to raise the events. Also notice the use of the Action(Of T) generic template. This is provided by the .NET framework as a helper when declaring events that have a custom EventArgs subclass as a single parameter . There’s also a corresponding EventHandler(Of T) template to help when declar ing the standard sender and EventArgs pattern for event methods. RunLocal In each of the five public methods, DataPortal must determine whether the business developer has applied the <RunLocal()> attr ibute to the business method on their business class. The RunLocal() method checks for the attribute, returning a Boolean indicating whether it exists or not: Private Function RunLocal(ByVal method As MethodInfo) As Boolean Return Attribute.IsDefined(method, GetType(RunLocalAttribute)) End Function While not strictly necessarily, this helper method streamlines the more complex code else- wher e in the class . Cr eating the Proxy Object The primary function of Csla.DataPortal is to determine the appropriate network protocol (if any) to be used when inter acting with Csla.Server.DataPortal. Each pr otocol is managed by a proxy object that implements the Csla.DataPortalClient.IDataPortalProxy interface. This interface will be discussed shortly, but for now it is enough to know that it ensures that all proxy classes imple- ment the methods required by Csla.DataPortal. The pr o xy object to be used is defined in the application ’ s configuration file. That’s the web.config file for ASP .NET applications , and myprogram.exe.config for W indows applications (where myprogram is the name of your program). Within Visual Studio, a Windows configuration file is named app.config, so I’ll refer to them as app.config files from here forward. CHAPTER 4 ■ DATA ACCESS AND SECURITY190 6315_c04_final.qxd 4/13/06 12:33 PM Page 190 Config files can include an <appSettings> section to store application settings, and it is in this section that the CSLA .NET configuration settings are located. The following shows how this section would look for an application set to use the .NET Remoting technology: <appSettings> <add key="CslaDataPortalProxy" value="Csla.DataPortalClient.RemotingProxy, Csla"/> <add key="CslaDataPortalUrl" value="http://servername/sitename/RemotingPortal.rem"/> < /appSettings> Of course, servername and sitename would correspond to a real web server and virtual root. The CslaDataPortalProxy key defines the proxy class that should be used by Csla.DataPortal. The CslaDataPortalUrl key is defined and used by the proxy object itself. Different proxy objects may require or support different keys for their own configuration data. The GetDataPortalProxy() method uses this information to create an instance of the correct proxy object: Private mLocalPortal As DataPortalClient.IDataPortalProxy Private mPortal As DataPortalClient.IDataPortalProxy Private Function GetDataPortalProxy( _ ByVal forceLocal As Boolean) As DataPortalClient.IDataPortalProxy If forceLocal Then If mLocalPortal Is Nothing Then mLocalPortal = New DataPortalClient.LocalProxy End If Return mLocalPortal Else If mPortal Is Nothing Then Dim proxyTypeName As String = ApplicationContext.DataPortalProxy If proxyTypeName = "Local" Then mPortal = New DataPortalClient.LocalProxy Else Dim typeName As String = _ proxyTypeName.Substring(0, proxyTypeName.IndexOf(",")).Trim Dim assemblyName As String = _ proxyTypeName.Substring(proxyTypeName.IndexOf(",") + 1).Trim mPortal = DirectCast(Activator.CreateInstance(assemblyName, _ typeName).Unwrap, DataPortalClient.IDataPortalProxy) End If End If Return mPortal End If End Function For both local and remote proxy objects, once the proxy has been created, it is cached in a Shared field. (Remember that all fields, methods, and properties in a Module are effectively Shared.) This avoids recreating the proxy object for every data portal call. If the forceLocal par ameter is True, then only a local pr o xy is r eturned. The Csla. DataPortalClient.LocalProxy object is a special proxy that doesn’t use any network protocols at all, but rather runs the “server-side” data portal components directly within the client process. This class will be covered later in the chapter. CHAPTER 4 ■ DATA ACCESS AND SECURITY 191 6315_c04_final.qxd 4/13/06 12:33 PM Page 191 When forceLocal is False, the real work begins. First, the proxy string is retrieved from the CslaDataPortalProxy key in the config file by calling the ApplicationContext.DataPortalProxy property. The ApplicationContext class is covered later in the chapter, but this property reads the config file and returns the value associated with the CslaDataPortalProxy key. If that key value is "Local", then again an instance of the LocalProxy class is created and returned. The ApplicationContext.DataPortalProxy method also returns a LocalProxy object if t he key is not found in the config file. This makes L ocalProxy t he default proxy. If some other config value is returned, then it is parsed and used to create an instance of the appropriate proxy class: Dim typeName As String = _ proxyTypeName.Substring(0, proxyTypeName.IndexOf(",")).Trim Dim assemblyName As String = _ proxyTypeName.Substring(proxyTypeName.IndexOf(",") + 1).Trim mPortal = DirectCast(Activator.CreateInstance(assemblyName, _ typeName).Unwrap, DataPortalClient.IDataPortalProxy) In the preceding <appSettings> example, notice that the value is a comma-separated value with the full class name on the left and the assembly name on the right. This follows the .NET standar d for describing classes that are to be dynamically loaded. The config value is parsed to pull out the full type name and assembly name. Then Activator.CreateInstance() is called to create an instance of the object. The .NET runtime automatically loads the assembly if needed. The object returned from Activator.CreateInstance() isn’t the actual proxy object. Instead, it is an internal .NET object representing the underlying object. The Unwrap() method returns the real proxy object that was dynamically loaded. The final result is that the appropriate pr oxy object is loaded into memory and returned for use by the code in Csla.DataPortal. Data Access Methods The next step is to implement the five primary methods in the client-side DataPortal. Most of the hard work is handled by the code implemented thus far in the “Channel Adapter” section and in the MethodCaller class, so implementing these will be pretty straightforward. All five will follow the same basic flow: • Get the MethodInfo for the business method to be ultimately invoked. • G et the data por tal pr oxy object. • Create a DataPortalContext object. • Raise the DataPortalInvoke event. • D elegate the call to the proxy object (and thus to the server). • Handle and throw any exceptions. • Restore the GlobalContext returned from the server. • Raise the DataPortalInvokeComplete ev ent. • Return the resulting business object (if appropriate). Let’s look at the Fetch() method in detail, followed by the minor differences required to imple- ment the other four methods . CHAPTER 4 ■ DATA ACCESS AND SECURITY192 6315_c04_final.qxd 4/13/06 12:33 PM Page 192 Fetch There are two Fetch() methods: a generic one to provide a strongly typed result, and the actual implementation: Public Function Fetch(Of T)(ByVal criteria As Object) As T Return DirectCast(Fetch(criteria), T) End Function Public Function Fetch(ByVal criteria As Object) As Object Dim result As Server.DataPortalResult Dim method As MethodInfo = _ MethodCaller.GetMethod( _ MethodCaller.GetObjectType(criteria), "DataPortal_Fetch", criteria) Dim proxy As DataPortalClient.IDataPortalProxy proxy = GetDataPortalProxy(RunLocal(method)) Dim dpContext As New Server.DataPortalContext( _ GetPrincipal, proxy.IsServerRemote) OnDataPortalInvoke(New DataPortalEventArgs(dpContext)) Try result = proxy.Fetch(criteria, dpContext) Catch ex As Server.DataPortalException result = ex.Result If proxy.IsServerRemote Then ApplicationContext.SetGlobalContext(result.GlobalContext) End If Throw New DataPortalException("DataPortal.Fetch " & _ My.Resources.Failed, ex.InnerException, result.ReturnObject) End Try If proxy.IsServerRemote Then ApplicationContext.SetGlobalContext(result.GlobalContext) End If OnDataPortalInvokeComplete(New DataPortalEventArgs(dpContext)) Return result.ReturnObject End Function The generic method simply casts the result so that the calling code doesn’t have to. Remem- ber that the data portal can return virtually any type of object, and so the actual Fetch() method implementation must deal with r esults of type Object. Looking at the code, you should see all the steps listed in the preceding bulleted list. The first is to r etr iev e the MethodInfo for the business method that will be ultimately inv oked on the ser ver: Dim method As MethodInfo = _ MethodCaller.GetMethod( _ MethodCaller.GetObjectType(criteria), "DataPortal_Fetch", criteria) CHAPTER 4 ■ DATA ACCESS AND SECURITY 193 6315_c04_final.qxd 4/13/06 12:33 PM Page 193 [...]...6315_c 04_ final.qxd 1 94 4/13/06 12:33 PM Page 1 94 CHAPTER 4 s DATA ACCESS AND SECURITY This MethodInfo object is immediately used to determine whether the attribute has been applied to the method on the business class This value is used as a parameter to the GetDataPortalProxy() method, which returns... created in step 2 4 Use the Component Services management console to set the application root directory to the directory created in step 2, as shown in Figure 4- 10 5 Use the Component Services management console to set any other application settings as appropriate for your environment 209 6315_c 04_ final.qxd 210 4/ 13/06 12:33 PM Page 210 CHAPTER 4 s DATA ACCESS AND SECURITY Figure 4- 10 Setting the application... deserialized to create a server-side copy of the FetchRequest object created on the client: Dim request As FetchRequest = _ DirectCast(Deserialize(requestData), FetchRequest) 213 6315_c 04_ final.qxd 2 14 4/13/06 12: 34 PM Page 2 14 CHAPTER 4 s DATA ACCESS AND SECURITY The FetchRequest class is a DTO that simply defines the data to be passed from client to server when Fetch() is called It looks like this: ... Server.DataPortalResult _ Implements Server.IDataPortalServer.Delete Dim portal As New Server.DataPortal Return portal.Delete(criteria, context) End Function End Class 203 6315_c 04_ final.qxd 2 04 4/13/06 12:33 PM Page 2 04 CHAPTER 4 s DATA ACCESS AND SECURITY Notice that it not only inherits from MarshalByRefObject, but it also implements IDataPortalServer Recall that this is the common interface required... rest of the process is fundamentally the same as Create() and Fetch() 6315_c 04_ final.qxd 4/ 13/06 12:33 PM Page 197 CHAPTER 4 s DATA ACCESS AND SECURITY Execute The Update() method includes code to call DataPortal_Execute() on a business object that inherits from Csla.CommandBase That’s fine, but may not be intuitive to a business developer The Execute() method is intended to make the data portal API... technology, but rather as an 6315_c 04_ final.qxd 4/ 13/06 12:33 PM Page 211 CHAPTER 4 s DATA ACCESS AND SECURITY interop technology Due to this, Web Services is not normally able to support the concept of mobile objects The WebServicesProxy and corresponding WebServicePortal classes will overcome this limitation by manually using the NET BinaryFormatter to serialize and deserialize the objects The result of such... mobile objects as required by CSLA NET To overcome this limitation, each of the data methods in WebServicesProxy explicitly uses the NET BinaryFormatter to serialize and deserialize objects: Public Function Fetch( _ ByVal criteria As Object, _ ByVal context As Server.DataPortalContext) As Server.DataPortalResult _ Implements Server.IDataPortalServer.Fetch 211 6315_c 04_ final.qxd 212 4/ 13/06 12: 34 PM Page... Csla.Server.Hosts.RemotingPortal objects Csla.Server.Hosts.RemotingPortal You’ve seen the client proxy for the NET Remoting channel It requires that a RemotingPortal object be hosted on an IIS server To expose a server-side object through remoting, that object must inherit 6315_c 04_ final.qxd 4/ 13/06 12:33 PM Page 203 CHAPTER 4 s DATA ACCESS AND SECURITY from System.MarshalByRefObject Such objects are often referred... service data portal, it needs to do the following: 6315_c 04_ final.qxd 4/ 13/06 12: 34 PM Page 215 CHAPTER 4 s DATA ACCESS AND SECURITY 1 Set up a virtual root 2 Put Csla.dll into the Bin directory 3 Create an asmx file referencing WebServicePortal in the virtual directory The asmx file needs to contain the following single line: This... transactional context if requested by the business object The CSLA NET framework allows a business developer to choose between manually handling transactions, using Enterprise Services (COM+) transactions, or using System.Transactions The business developer indicates his preference through the use of the custom Csla TransactionalAttribute Earlier in the chapter, Table 4- 4 listed all the possible options when . currentType.BaseType Loop Until currentType Is Nothing CHAPTER 4 ■ DATA ACCESS AND SECURITY1 84 6315_c 04_ final.qxd 4/ 13/06 12:33 PM Page 1 84 As soon as a match is found, the loop is terminated and. which is used to update the context on the client: CHAPTER 4 ■ DATA ACCESS AND SECURITY1 94 6315_c 04_ final.qxd 4/ 13/06 12:33 PM Page 1 94 If proxy.IsServerRemote Then ApplicationContext.SetGlobalContext(result.GlobalContext) End. inherit CHAPTER 4 ■ DATA ACCESS AND SECURITY202 6315_c 04_ final.qxd 4/ 13/06 12:33 PM Page 202 from System.MarshalByRefObject. Such objects are often referred to as MBROs (marshal-by-refer- ence objects) .

Ngày đăng: 12/08/2014, 16:21

TỪ KHÓA LIÊN QUAN