1: public class LinqToXMLExportProvider : ExportProvider
2: {
3: //Key is the contract name, value is the assembly qualified name of the implementing class....
4: private Dictionary<string, string> _mappings;
5: private FileSystemWatcher _watcher;
6:
7: public LinqToXMLExportProvider(string mappingFile)
8: {
9: _mappings = ParseFile(mappingFile);
10: _watcher = new FileSystemWatcher(Path.GetDirectoryName(mappingFile), Path.GetFileName(mappingFile));
11: _watcher.Changed += new FileSystemEventHandler(_watcher_Changed);
12: _watcher.NotifyFilter = NotifyFilters.LastWrite;
13: _watcher.EnableRaisingEvents = true;
14:
15: }
16:
17: void _watcher_Changed(object sender, FileSystemEventArgs e)
18: {
19: Dictionary<string, string> newMappings = ParseFile(e.FullPath);
20:
21: //Get the keys that are new in the export file....
22: List<ExportDefinition> newDefinitions = newMappings.Keys.Except(_mappings.Keys).Select(
23: (key)=>CreateExportDefintion(key)).ToList();
24: //Get the keys that are removed in the export file
25: List<ExportDefinition> removedDefinitions = _mappings.Keys.Except(newMappings.Keys).Select(
26: (key) => CreateExportDefintion(key)).ToList();
27:
28: // find the keys that may have changed values in the export file....
29: var result = from oldKV in _mappings
30: join newKV in newMappings on oldKV.Key equals newKV.Key
31: select new {OldKeyValue = oldKV, NewKeyValue = newKV};
32: foreach (var item in result)
33: {
34: if(item.OldKeyValue.Value != item.NewKeyValue.Value)
35: {
36: //If keys have changed value, the contract is both added and removed...
37: newDefinitions.Add(CreateExportDefintion(item.NewKeyValue.Key));
38: removedDefinitions.Add(CreateExportDefintion(item.OldKeyValue.Key));
39: }
40:
41: }
42:
43: _mappings = newMappings;
44: using (AtomicComposition atomic = new AtomicComposition())
45: {
46: OnExportsChanging(new ExportsChangeEventArgs(newDefinitions, removedDefinitions, atomic));
47: atomic.Complete();
48: }
49: OnExportsChanged(new ExportsChangeEventArgs(newDefinitions, removedDefinitions, null));
50: }
51:
52:
53: private ExportDefinition CreateExportDefintion(string contractName)
54: {
55: Dictionary<string, object> metaData = new Dictionary<string, object>();
56: metaData.Add(CompositionConstants.ExportTypeIdentityMetadataName, contractName);
57: return new ExportDefinition(contractName, metaData);
58: }
59:
60: private Dictionary<string, string> ParseFile(string mappingFile)
61: {
62: XElement mappings = XElement.Load(mappingFile);
63: return mappings.Elements().ToDictionary((el)=> el.Attribute("contract").Value,
64: (el=>el.Attribute("type").Value));
65: }
66:
67: protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition)
68: {
69:
70: List<Export> exports = new List<Export>();
71: string implementingType;
72: if (_mappings.TryGetValue(definition.ContractName, out implementingType))
73: {
74: Type t = Type.GetType(implementingType);
75: object instance = t.GetConstructor(Type.EmptyTypes).Invoke(null);
76: ExportDefinition exportDefintion = new ExportDefinition(definition.ContractName, new Dictionary<string, object>());
77: Export toAdd = new Export(exportDefintion, () => instance);
78: exports.Add(toAdd);
79: }
80: return exports;
81: }