Skip to content

Commit

Permalink
Added IDotNetifyConfiguration to simplify startup config.
Browse files Browse the repository at this point in the history
Dicky Suryadi committed Feb 16, 2017
1 parent 3b11762 commit fdf75de
Showing 6 changed files with 108 additions and 45 deletions.
33 changes: 33 additions & 0 deletions DotNetifyLib.Core/IDotNetifyConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using System.Reflection;

namespace DotNetify
{
public interface IDotNetifyConfiguration
{
/// <summary>
/// Provides a factory method to create view model instances.
/// The method accepts a class type and constructor arguments, and returns an instance of that type.
/// </summary>
void SetFactoryMethod(Func<Type, object[], object> factoryMethod);

/// <summary>
/// Register an assembly that has the view model classes.
/// </summary>
void RegisterAssembly(Assembly assembly);
void RegisterAssembly(string assemblyName);
}

public class DotNetifyConfiguration : IDotNetifyConfiguration
{
public void SetFactoryMethod(Func<Type, object[], object> factoryMethod) => VMController.CreateInstance = (type, args) => factoryMethod(type, args);

public void RegisterAssembly(Assembly assembly) => VMController.RegisterAssembly(assembly);

public void RegisterAssembly(string assemblyName) => VMController.RegisterAssembly(Assembly.Load(new AssemblyName(assemblyName)));

public void RegisterEntryAssembly() => VMController.RegisterAssembly(Assembly.GetEntryAssembly());

public bool HasAssembly => VMController._registeredAssemblies.Count > 0;
}
}
10 changes: 5 additions & 5 deletions DotNetifyLib.Core/VMController.cs
Original file line number Diff line number Diff line change
@@ -64,7 +64,7 @@ public class UnresolvedVMUpdateException : Exception { }
/// <summary>
/// This class encapsulates a view model information.
/// </summary>
protected class VMInfo
protected internal class VMInfo
{
/// <summary>
/// Instance of a view model.
@@ -80,22 +80,22 @@ protected class VMInfo
/// <summary>
/// List of known view model classes.
/// </summary>
protected static List<Type> _vmTypes = new List<Type>();
protected internal static List<Type> _vmTypes = new List<Type>();

/// <summary>
/// List of registered assemblies.
/// </summary>
protected static List<string> _registeredAssemblies = new List<string>();
protected internal static List<string> _registeredAssemblies = new List<string>();

/// <summary>
/// Active instances of view models.
/// </summary>
protected ConcurrentDictionary<string, VMInfo> _activeVMs = new ConcurrentDictionary<string, VMInfo>();
protected internal ConcurrentDictionary<string, VMInfo> _activeVMs = new ConcurrentDictionary<string, VMInfo>();

/// <summary>
/// Function invoked by the view model to provide response back to the client.
/// </summary>
protected readonly VMResponseDelegate _vmResponse;
protected internal readonly VMResponseDelegate _vmResponse;

#endregion

27 changes: 24 additions & 3 deletions DotNetifyLib.SignalR/Extensions/AppBuilderExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,36 @@
using System;
using System.Diagnostics;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

namespace DotNetify
{
public static class AppBuilderExtensions
{
public static IApplicationBuilder UseDotNetify(this IApplicationBuilder appBuilder)
public static IApplicationBuilder UseDotNetify(this IApplicationBuilder appBuilder, Action<IDotNetifyConfiguration> config = null)
{
// Use ASP.NET Core DI to provide view model instances by default, but you can always use your favorite IoC container.
var dotNetifyConfig = new DotNetifyConfiguration();

// Use ASP.NET Core DI to provide view model instances by default.
var provider = appBuilder.ApplicationServices;
VMController.CreateInstance = (type, args) => ActivatorUtilities.CreateInstance(provider, type, args ?? new object[] { });
dotNetifyConfig.SetFactoryMethod((type, args) =>
{
try
{
return ActivatorUtilities.CreateInstance(provider, type, args ?? new object[] { });
}
catch (Exception ex)
{
Trace.Fail(ex.Message);
throw ex;
}
});

config?.Invoke(dotNetifyConfig);

// If no view model assembly has been registered, default to the entry assembly.
if (!dotNetifyConfig.HasAssembly)
dotNetifyConfig.RegisterEntryAssembly();

return appBuilder;
}
15 changes: 8 additions & 7 deletions WebApplication.Core.React/Startup.cs
Original file line number Diff line number Diff line change
@@ -20,13 +20,14 @@ public class Startup
public void ConfigureServices( IServiceCollection services )
{
services.AddMvc();
services.AddMemoryCache();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddReact();
services.AddSignalR();
services.AddDotNetify();
services.AddLocalization();

services.AddMemoryCache(); // Required by dotNetify and ReactJS.NET.
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); // Required by ReactJS.NET.
services.AddSignalR(); // Required by dotNetify.

VMController.RegisterAssembly( GetType().GetTypeInfo().Assembly );
services.AddReact();
services.AddDotNetify();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -36,7 +37,7 @@ public void Configure( IApplicationBuilder app, IHostingEnvironment env, ILogger
app.UseStaticFiles();

app.UseWebSockets();
app.UseSignalR();
app.UseSignalR(); // Required by dotNetify.
app.UseDotNetify();

app.UseMvc(routes =>
30 changes: 18 additions & 12 deletions WebApplication.Core.React/ViewModels/GridViewVM.cs
Original file line number Diff line number Diff line change
@@ -2,8 +2,9 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows.Input;
using DotNetify;
using Microsoft.Extensions.Localization;
using ViewModels.Components.MaterialUI;
using DotNetify;

namespace ViewModels
{
@@ -50,10 +51,20 @@ public class EmployeeDetails
/// <summary>
/// List of employees.
/// </summary>
public IEnumerable<EmployeeMaster> Employees => _employeeService
.GetAll()
.Where(i => string.IsNullOrEmpty(EmployeeSearch) || i.FullName.ToLower().Contains(EmployeeSearch))
.Select(record => new EmployeeMaster(record));
public IEnumerable<EmployeeMaster> Employees
{
get
{
var result = _employeeService.GetAll()
.Where(i => string.IsNullOrEmpty(EmployeeSearch) || i.FullName.ToLower().Contains(EmployeeSearch))
.Select(record => new EmployeeMaster(record));

if (!result.Any(i => i.Id == SelectedId))
SelectedId = result.Count() > 0 ? result.First().Id : -1;

return result;
}
}

/// <summary>
/// If you use CRUD methods on a list, you must set the item key prop name of that list
@@ -68,11 +79,6 @@ public string EmployeeSearch
{
Set(value.ToLower());
Changed(nameof(Employees));

// Update current selection if it's not valid anymore.
var employees = Employees;
if (!employees.Any(i => i.Id == SelectedId))
SelectedId = employees.Count() > 0 ? employees.First().Id : -1;
}
}

@@ -157,12 +163,12 @@ public string ReportToSearch
/// Constructor.
/// </summary>
/// <param name="model">Employee model.</param>
public GridViewVM()
public GridViewVM( IStringLocalizer<GridViewVM> localizer)
{
// Normally this will be constructor-injected.
_employeeService = new EmployeeService();

SelectedId = _employeeService.GetAll().First().Id;
var test = localizer.GetAllStrings();
}
}
}
38 changes: 20 additions & 18 deletions WebApplication.Core/Startup.cs
Original file line number Diff line number Diff line change
@@ -33,12 +33,6 @@ public void ConfigureServices(IServiceCollection services)
services.AddSignalR(options => options.Hubs.EnableDetailedErrors = true);
services.AddMemoryCache();
services.AddDotNetify();

// Find the assembly "ViewModels.Examples" and register it to DotNetify.VMController.
// This will cause all the classes inside the assembly that inherits from DotNetify.BaseVM to be known as view models.
var vmAssembly = Assembly.Load(new AssemblyName("ViewModels.Examples"));
if (vmAssembly != null)
VMController.RegisterAssembly(vmAssembly);
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -60,19 +54,27 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF
app.UseWebSockets();
app.UseSignalR();

// Use ASP.NET Core DI to provide view model instances, but you can always use your favorite IoC container.
var provider = app.ApplicationServices;
VMController.CreateInstance = (type, args) =>
{
if (type == typeof(SimpleListVM) || type == typeof(BetterListVM))
args = new object[] { new EmployeeModel(7) };
else if (type == typeof(TreeViewVM) || type == typeof(GridViewVM) || type == typeof(CompositeViewVM))
args = new object[] { new EmployeeModel() };
else if (type == typeof(AFITop100VM))
args = new object[] { new AFITop100Model() };
app.UseDotNetify(config => {

// Find the assembly "ViewModels.Examples" and register it to DotNetify.VMController.
// This will cause all the classes inside the assembly that inherits from DotNetify.BaseVM to be known as view models.
config.RegisterAssembly("ViewModels.Examples");

return ActivatorUtilities.CreateInstance(provider, type, args ?? new object[] { });
};
// Set the factory method to provide view model instances, where you can use your favorite IoC container.
// If this isn't set, it will default to using ASP.NET Core DI container.
var provider = app.ApplicationServices;
config.SetFactoryMethod( (type, args) =>
{
if (type == typeof(SimpleListVM) || type == typeof(BetterListVM))
args = new object[] { new EmployeeModel(7) };
else if (type == typeof(TreeViewVM) || type == typeof(GridViewVM) || type == typeof(CompositeViewVM))
args = new object[] { new EmployeeModel() };
else if (type == typeof(AFITop100VM))
args = new object[] { new AFITop100Model() };

return ActivatorUtilities.CreateInstance(provider, type, args ?? new object[] { });
});
});
}
}
}

0 comments on commit fdf75de

Please sign in to comment.