-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
MvxAndroidSetup.cs
310 lines (248 loc) · 11.1 KB
/
MvxAndroidSetup.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MS-PL license.
// See the LICENSE file in the project root for more information.
using System.Reflection;
using Android.Content;
using Android.Views;
using MvvmCross.Binding;
using MvvmCross.Binding.Binders;
using MvvmCross.Binding.BindingContext;
using MvvmCross.Binding.Bindings.Target.Construction;
using MvvmCross.Converters;
using MvvmCross.Core;
using MvvmCross.Exceptions;
using MvvmCross.IoC;
using MvvmCross.Platforms.Android.Binding;
using MvvmCross.Platforms.Android.Binding.Binders.ViewTypeResolvers;
using MvvmCross.Platforms.Android.Binding.Views;
using MvvmCross.Platforms.Android.Presenters;
using MvvmCross.Platforms.Android.Views;
using MvvmCross.Presenters;
using MvvmCross.ViewModels;
using MvvmCross.Views;
namespace MvvmCross.Platforms.Android.Core
{
#nullable enable
public abstract class MvxAndroidSetup
: MvxSetup, IMvxAndroidGlobals, IMvxAndroidSetup
{
private MvxCurrentTopActivity? _currentTopActivity;
private IMvxAndroidViewPresenter? _presenter;
public void PlatformInitialize(Activity activity)
{
ArgumentNullException.ThrowIfNull(activity);
ArgumentNullException.ThrowIfNull(activity.Application);
PlatformInitialize(activity.Application);
// this is needed for when App is rehydrated from being killed by Android in the background
_currentTopActivity?.OnActivityCreated(activity, null);
}
public void PlatformInitialize(Application application)
{
ArgumentNullException.ThrowIfNull(application);
if (_currentTopActivity != null)
return;
_currentTopActivity = new MvxCurrentTopActivity();
application.RegisterActivityLifecycleCallbacks(_currentTopActivity);
}
public virtual Assembly ExecutableAssembly => ViewAssemblies.FirstOrDefault() ?? GetType().Assembly;
public Context? ApplicationContext => _currentTopActivity?.Activity?.ApplicationContext;
protected override void InitializeFirstChance(IMvxIoCProvider iocProvider)
{
ValidateArguments(iocProvider);
InitializeLifetimeMonitor(iocProvider);
InitializeAndroidCurrentTopActivity(iocProvider);
RegisterPresenter(iocProvider);
iocProvider.RegisterSingleton<IMvxAndroidGlobals>(this);
var intentResultRouter = new MvxIntentResultSink();
iocProvider.RegisterSingleton<IMvxIntentResultSink>(intentResultRouter);
iocProvider.RegisterSingleton<IMvxIntentResultSource>(intentResultRouter);
var viewModelTemporaryCache = new MvxSingleViewModelCache();
iocProvider.RegisterSingleton<IMvxSingleViewModelCache>(viewModelTemporaryCache);
var viewModelMultiTemporaryCache = new MvxMultipleViewModelCache();
iocProvider.RegisterSingleton<IMvxMultipleViewModelCache>(viewModelMultiTemporaryCache);
base.InitializeFirstChance(iocProvider);
}
protected virtual void InitializeAndroidCurrentTopActivity(IMvxIoCProvider iocProvider)
{
ValidateArguments(iocProvider);
var currentTopActivity = CreateAndroidCurrentTopActivity();
iocProvider.RegisterSingleton(currentTopActivity);
}
protected virtual IMvxAndroidCurrentTopActivity CreateAndroidCurrentTopActivity()
{
if (_currentTopActivity == null)
throw new InvalidOperationException($"Please call {nameof(PlatformInitialize)} first");
return _currentTopActivity;
}
protected virtual void InitializeLifetimeMonitor(IMvxIoCProvider iocProvider)
{
ValidateArguments(iocProvider);
var lifetimeMonitor = CreateLifetimeMonitor();
iocProvider.RegisterSingleton<IMvxAndroidActivityLifetimeListener>(lifetimeMonitor);
iocProvider.RegisterSingleton<IMvxLifetime>(lifetimeMonitor);
}
protected virtual MvxAndroidLifetimeMonitor CreateLifetimeMonitor()
{
return new MvxAndroidLifetimeMonitor();
}
protected virtual void InitializeSavedStateConverter(IMvxIoCProvider iocProvider)
{
ValidateArguments(iocProvider);
var converter = CreateSavedStateConverter();
iocProvider.RegisterSingleton(converter);
}
protected virtual IMvxSavedStateConverter CreateSavedStateConverter()
{
return new MvxSavedStateConverter();
}
protected sealed override IMvxViewsContainer CreateViewsContainer(IMvxIoCProvider iocProvider)
{
ValidateArguments(iocProvider);
if (ApplicationContext == null)
throw new InvalidOperationException("Cannot create Views Container without ApplicationContext");
var container = CreateViewsContainer(ApplicationContext);
iocProvider.RegisterSingleton<IMvxAndroidViewModelRequestTranslator>(container);
iocProvider.RegisterSingleton<IMvxAndroidViewModelLoader>(container);
if (container is not MvxViewsContainer viewsContainer)
throw new MvxException("CreateViewsContainer must return an MvxViewsContainer");
return viewsContainer;
}
protected virtual IMvxAndroidViewsContainer CreateViewsContainer(Context applicationContext)
{
return new MvxAndroidViewsContainer(applicationContext);
}
protected IMvxAndroidViewPresenter Presenter
{
get
{
_presenter ??= CreateViewPresenter();
return _presenter;
}
}
protected virtual IMvxAndroidViewPresenter CreateViewPresenter()
{
return new MvxAndroidViewPresenter(AndroidViewAssemblies);
}
protected override IMvxViewDispatcher CreateViewDispatcher()
{
return new MvxAndroidViewDispatcher(Presenter);
}
protected virtual void RegisterPresenter(IMvxIoCProvider iocProvider)
{
ValidateArguments(iocProvider);
var presenter = Presenter;
iocProvider.RegisterSingleton(presenter);
iocProvider.RegisterSingleton<IMvxViewPresenter>(presenter);
}
protected override void InitializeLastChance(IMvxIoCProvider iocProvider)
{
ValidateArguments(iocProvider);
InitializeSavedStateConverter(iocProvider);
InitializeBindingBuilder(iocProvider);
base.InitializeLastChance(iocProvider);
}
protected virtual void InitializeBindingBuilder(IMvxIoCProvider iocProvider)
{
ValidateArguments(iocProvider);
var bindingBuilder = CreateBindingBuilder();
RegisterBindingBuilderCallbacks(iocProvider);
bindingBuilder.DoRegistration(iocProvider);
}
protected virtual void RegisterBindingBuilderCallbacks(IMvxIoCProvider iocProvider)
{
ValidateArguments(iocProvider);
iocProvider.CallbackWhenRegistered<IMvxValueConverterRegistry>(FillValueConverters);
iocProvider.CallbackWhenRegistered<IMvxTargetBindingFactoryRegistry>(FillTargetFactories);
iocProvider.CallbackWhenRegistered<IMvxBindingNameRegistry>(FillBindingNames);
iocProvider.CallbackWhenRegistered<IMvxTypeCache<View>>(FillViewTypes);
iocProvider.CallbackWhenRegistered<IMvxAxmlNameViewTypeResolver>(FillAxmlViewTypeResolver);
iocProvider.CallbackWhenRegistered<IMvxNamespaceListViewTypeResolver>(FillNamespaceListViewTypeResolver);
}
protected virtual MvxBindingBuilder CreateBindingBuilder()
{
return new MvxAndroidBindingBuilder();
}
protected virtual void FillViewTypes(IMvxTypeCache<View> cache)
{
ArgumentNullException.ThrowIfNull(cache);
foreach (var assembly in AndroidViewAssemblies)
{
cache.AddAssembly(assembly);
}
}
protected virtual void FillBindingNames(IMvxBindingNameRegistry registry)
{
// this base class does nothing
}
protected virtual void FillAxmlViewTypeResolver(IMvxAxmlNameViewTypeResolver viewTypeResolver)
{
ArgumentNullException.ThrowIfNull(viewTypeResolver);
foreach (var kvp in ViewNamespaceAbbreviations)
{
viewTypeResolver.ViewNamespaceAbbreviations[kvp.Key] = kvp.Value;
}
}
protected virtual void FillNamespaceListViewTypeResolver(IMvxNamespaceListViewTypeResolver viewTypeResolver)
{
ArgumentNullException.ThrowIfNull(viewTypeResolver);
foreach (var viewNamespace in ViewNamespaces)
{
viewTypeResolver.Add(viewNamespace);
}
}
protected virtual void FillValueConverters(IMvxValueConverterRegistry registry)
{
ArgumentNullException.ThrowIfNull(registry);
registry.Fill(ValueConverterAssemblies);
registry.Fill(ValueConverterHolders);
}
protected virtual IEnumerable<Type> ValueConverterHolders => new List<Type>();
protected virtual IEnumerable<Assembly> ValueConverterAssemblies
{
get
{
var toReturn = new List<Assembly>();
toReturn.AddRange(GetViewModelAssemblies());
toReturn.AddRange(GetViewAssemblies());
return toReturn;
}
}
protected virtual IDictionary<string, string> ViewNamespaceAbbreviations => new Dictionary<string, string>
{
{ "Mvx", "mvvmcross.platforms.android.binding.views" }
};
protected virtual IEnumerable<string> ViewNamespaces => new List<string>
{
"Android.Views",
"Android.Widget",
"Android.Webkit",
"MvvmCross.Platforms.Android.Views",
"MvvmCross.Platforms.Android.Binding.Views"
};
protected virtual IEnumerable<Assembly> AndroidViewAssemblies => new List<Assembly>()
{
typeof(View).Assembly,
typeof(MvxDatePicker).Assembly,
GetType().Assembly,
};
protected virtual void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)
{
// nothing to do in this base class
}
protected override IMvxNameMapping CreateViewToViewModelNaming()
{
return new MvxPostfixAwareViewToViewModelNameMapping("View", "Activity", "Fragment");
}
}
public abstract class MvxAndroidSetup<TApplication> : MvxAndroidSetup
where TApplication : class, IMvxApplication, new()
{
protected override IMvxApplication CreateApp(IMvxIoCProvider iocProvider) =>
iocProvider.IoCConstruct<TApplication>();
public override IEnumerable<Assembly> GetViewModelAssemblies()
{
return new[] { typeof(TApplication).GetTypeInfo().Assembly };
}
}
#nullable restore
}