Fixing an issue with output parameters that are of type IntPtr
[castle.git] / Facilities / DynamicLoader / Castle.Facilities.DynamicLoader / DynamicLoaderActivator.cs
blobe444647e079f2c0d19ccce40c957fa05750ebce5
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.Facilities.DynamicLoader
17 using System;
18 using System.Runtime.Remoting;
19 using System.Runtime.Remoting.Lifetime;
20 using Castle.Core;
21 using Castle.MicroKernel;
22 using Castle.MicroKernel.ComponentActivator;
23 using Castle.MicroKernel.Facilities;
25 /// <summary>
26 /// Delegates the creation of components to a <see cref="RemoteLoader"/>,
27 /// which creates the component on a different <see cref="AppDomain"/>.
28 /// </summary>
29 public class DynamicLoaderActivator : DefaultComponentActivator, IDisposable
31 private readonly RemoteLoader loader;
32 private ClientSponsor keepAliveSponsor;
33 private TimeSpan sponsorTimeout = TimeSpan.FromMinutes(2);
35 /// <summary>
36 /// Creates a new <see cref="DynamicLoaderActivator"/>.
37 /// </summary>
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(
44 String.Format(
45 "The implementation for the component '{0}' must inherit from System.MarshalByRefObject in order to be created in an isolated AppDomain.",
46 model.Name));
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));
54 /// <summary>
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.
58 /// </summary>
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);
68 if (lease != null)
70 lease.Register(keepAliveSponsor);
71 lease.Renew(sponsorTimeout);
74 return instance;
77 /// <summary>
78 /// Disposes an object, and unregisters it from the <see cref="ClientSponsor"/>.
79 /// </summary>
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);
90 /// <summary>
91 /// Closes the <see cref="ClientSponsor"/> used to keep remote objects alive.
92 /// </summary>
93 public void Dispose()
95 if (keepAliveSponsor != null)
96 keepAliveSponsor.Close();