/
StudioViewLocator.cs
118 lines (100 loc) · 4.05 KB
/
StudioViewLocator.cs
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
108
109
110
111
112
113
114
115
116
117
118
namespace Raven.Studio
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Windows;
using Caliburn.Micro;
public static class StudioViewLocator
{
public static UIElement LocateForModelType(
Type modelType,
DependencyObject viewLocation,
object context,
Func<Type, DependencyObject, object, UIElement> original)
{
// case 1: types that are not in the Studio assembly
if (modelType.Assembly != Assembly.GetExecutingAssembly())
{
UIElement view;
if (TryResolveViewFromExternalAssembly(modelType, context, out view))
{
return view;
}
}
// case 2: simplified convention
string viewTypeName = modelType.FullName + "View";
Type viewType = (from assmebly in AssemblySource.Instance
from type in assmebly.GetExportedTypes()
where type.FullName == viewTypeName
select type).FirstOrDefault();
if (viewType != null)
return ViewLocator.GetOrCreateViewType(viewType);
// case 3: apply the default when all else fails
return original(modelType, viewLocation, context);
}
static bool TryResolveViewFromExternalAssembly(Type modelType, object context, out UIElement view)
{
view = null;
if (TryResolveViewFromPluginAssembly(modelType, context, out view))
{
return true;
}
return false;
}
static bool TryResolveViewFromApi(Type modelType, object context, out UIElement view)
{
view = null;
var name = "Raven.Studio.Data." + modelType.Name;
if (name.Contains("`"))
name = name.Substring(0, name.IndexOf("`"));
var viewType = GetViewType(modelType, context, AssemblySource.Instance.ToArray());
if (viewType != null)
{
view = ViewLocator.GetOrCreateViewType(viewType);
return true;
}
return false;
}
static bool TryResolveViewFromPluginAssembly(Type modelType, object context, out UIElement view)
{
view = null;
var viewType = GetViewType(modelType, context, modelType.Assembly);
if (viewType != null)
{
view = ViewLocator.GetOrCreateViewType(viewType);
return true;
}
return false;
}
static Type GetViewType(Type modelType, object context, params Assembly[] sources)
{
foreach (var viewTypeName in PossibleViewTypeNames(modelType, context))
{
var viewType = (from assembly in sources
from type in assembly.GetExportedTypes()
where type.FullName == viewTypeName
select type).FirstOrDefault();
if (viewType != null) return viewType;
}
return null;
}
static IEnumerable<string> PossibleViewTypeNames(Type modelType, object context)
{
return PossibleViewTypeNamesInternal(modelType.FullName, context)
.Where(x => x != modelType.FullName);
}
static IEnumerable<string> PossibleViewTypeNamesInternal(string fullName, object context)
{
if (context != null)
{
yield return fullName.Remove(fullName.Length - 4, 4);
yield return fullName + "." + context;
}
yield return fullName + "View";
yield return fullName.Replace("Model", "View");
yield return fullName.Replace("ViewModel", "View");
}
}
}