-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathAppDomainNameServer.cs
More file actions
107 lines (89 loc) · 3.72 KB
/
Copy pathAppDomainNameServer.cs
File metadata and controls
107 lines (89 loc) · 3.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace AppDomainMessaging
{
[Serializable]
public sealed class AppDomainNameServer
{
private readonly Dictionary<string, AppDomainNameRecord> _records;
private readonly Dictionary<string, AppDomainCacheRecord> _cache;
private readonly string _workspacePath;
public AppDomainNameServer()
{
_records = new Dictionary<string, AppDomainNameRecord>(StringComparer.InvariantCultureIgnoreCase);
_cache = new Dictionary<string, AppDomainCacheRecord>(StringComparer.InvariantCultureIgnoreCase);
//***** TODO:Configure;
_workspacePath = AppDomain.CurrentDomain.BaseDirectory;
}
public IReadOnlyList<AppDomainNameRecord> Records => _records.Values.ToList().AsReadOnly();
public void Add(AppDomainNameRecord nameRecord)
{
_records.Add(nameRecord.Name, nameRecord);
}
public void Add(string name, string location)
{
Add(new AppDomainNameRecord(name, location));
}
internal AppDomainProxy Resolve(string name, out Exception exception)
{
//*****
exception = null;
//***** Return if exists and not expired. Else flush and reload;
if (_cache.ContainsKey(name))
{
if (!_cache[name].Expired) return _cache[name].Proxy;
Flush(name);
}
//***** TODO:Custom exception;
if (!_records.ContainsKey(name))
{
exception = new Exception($"Unknown host: {name}");
return null;
}
var nameRecord = _records[name];
//***** TODO:Set workspace as application base;
//***** TODO:Security;
var appDomainSetup = new AppDomainSetup();
var appDomain = AppDomain.CreateDomain(nameRecord.Name, null, appDomainSetup);
var appDomainProxyType = typeof(AppDomainProxy);
var appDomainProxy = (AppDomainProxy) appDomain.CreateInstanceAndUnwrap(appDomainProxyType.Assembly.FullName, appDomainProxyType.FullName);
//***** Move to workspace;
if (!File.Exists(nameRecord.Location))
throw new FileNotFoundException();
//***** TODO:Use last modified time;
var workspaceLocation = $@"{_workspacePath}{Path.GetFileName(nameRecord.Location)}.{DateTime.Now.Ticks}";
File.Copy(nameRecord.Location, workspaceLocation);
//*****
appDomainProxy.LoadFrom(workspaceLocation);
_cache.Add(nameRecord.Name, new AppDomainCacheRecord(appDomain, appDomainProxy));
//*****
return _cache[name].Proxy;
}
internal void Flush(string name = null)
{
//*****
if (!string.IsNullOrWhiteSpace(name))
{
if (!_cache.ContainsKey(name)) throw new Exception();
var item = _cache[name];
AppDomain.Unload(item.Domain);
_cache.Remove(name);
return;
}
//*****
foreach (var item in _cache)
{
/*System.Diagnostics.Debug.WriteLine(item.Value.Domain.Id);
System.Diagnostics.Debug.WriteLine(item.Value.Domain.FriendlyName);
System.Diagnostics.Debug.WriteLine(item.Value.Domain.IsDefaultAppDomain());
System.Diagnostics.Debug.WriteLine(item.Value.Domain.IsFinalizingForUnload());*/
AppDomain.Unload(item.Value.Domain);
}
//*****
_cache.Clear();
_records.Clear();
}
}
}