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
.Facilities
.DynamicLoader
18 using System
.Runtime
.Remoting
;
19 using System
.Runtime
.Remoting
.Lifetime
;
21 using Castle
.MicroKernel
;
22 using Castle
.MicroKernel
.ComponentActivator
;
23 using Castle
.MicroKernel
.Facilities
;
26 /// Delegates the creation of components to a <see cref="RemoteLoader"/>,
27 /// which creates the component on a different <see cref="AppDomain"/>.
29 public class DynamicLoaderActivator
: DefaultComponentActivator
, IDisposable
31 private readonly RemoteLoader loader
;
32 private ClientSponsor keepAliveSponsor
;
33 private TimeSpan sponsorTimeout
= TimeSpan
.FromMinutes(2);
36 /// Creates a new <see cref="DynamicLoaderActivator"/>.
38 public DynamicLoaderActivator(ComponentModel model
, IKernel kernel
, ComponentInstanceDelegate onCreation
,
39 ComponentInstanceDelegate onDestruction
)
40 : base(model
, kernel
, onCreation
, onDestruction
)
42 if (!model
.Implementation
.IsSubclassOf(typeof(MarshalByRefObject
)))
43 throw new FacilityException(
45 "The implementation for the component '{0}' must inherit from System.MarshalByRefObject in order to be created in an isolated AppDomain.",
48 this.loader
= (RemoteLoader
) model
.ExtendedProperties
["dynamicLoader.loader"];
50 if (this.loader
== null)
51 throw new FacilityException(String
.Format("A remote loader was not created for component '{0}'.", model
.Name
));
55 /// Creates the component instance by calling the <see cref="RemoteLoader.CreateRemoteInstance"/>
56 /// method. The component is then registered with the <see cref="ClientSponsor"/>
57 /// with a renewal time of 2 minutes, in order to stay alive forever.
59 protected override object CreateInstance(CreationContext context
, object[] arguments
, Type
[] signature
)
61 object instance
= loader
.CreateRemoteInstance(Model
, context
, arguments
, signature
);
63 if (keepAliveSponsor
== null)
64 keepAliveSponsor
= new ClientSponsor(sponsorTimeout
);
66 MarshalByRefObject mbro
= (MarshalByRefObject
) instance
;
67 ILease lease
= (ILease
) RemotingServices
.GetLifetimeService(mbro
);
70 lease
.Register(keepAliveSponsor
);
71 lease
.Renew(sponsorTimeout
);
78 /// Disposes an object, and unregisters it from the <see cref="ClientSponsor"/>.
80 /// <param name="instance">The object being destroyed</param>
81 public override void Destroy(object instance
)
83 if (instance
is IDisposable
)
84 ((IDisposable
) instance
).Dispose();
86 if (keepAliveSponsor
!= null)
87 keepAliveSponsor
.Unregister((MarshalByRefObject
) instance
);
91 /// Closes the <see cref="ClientSponsor"/> used to keep remote objects alive.
95 if (keepAliveSponsor
!= null)
96 keepAliveSponsor
.Close();