Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,10 @@
</div>

@functions {
// It would be cleaner if we could mark properties with [FromAttribute] or similar,
// instead of having to extract them from a dictionary manually.
private int currentCount;
private Action resetCounterCallback;

protected override void ReceiveParameters(IDictionary<string, object> parameters)
{
currentCount = (int)parameters["current-count"];
resetCounterCallback = (Action)parameters["on-reset"];
}
[FromAttribute("current-count")]
private int currentCount { get; set; } //works with properties

[FromAttribute("on-reset")]
private Action resetCounterCallback; //and fields
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
@using Task = Blazor.Runtime.FakeBcl.Task; // Temporary until Mono supports Task
@using HttpClient = Blazor.Runtime.FakeBcl.HttpClient; // Temporary until Mono supports HttpClient
@using ClientServerApp.Client
@using Blazor.Runtime.Components
@using ClientServerApp.Shared
@using System.Net.Http
24 changes: 24 additions & 0 deletions src/Blazor.Runtime/Components/FromAttributeAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Blazor.Runtime.Components
{
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class FromAttributeAttribute : Attribute
{
public string AttributeName {get; set;}
public bool IsOptional { get; set; }

public FromAttributeAttribute(string attributeName)
{
AttributeName = attributeName;
}

public FromAttributeAttribute(string attributeName, bool isOptional)
{
AttributeName = attributeName;
IsOptional = isOptional;
}
}
}
45 changes: 41 additions & 4 deletions src/Blazor.Runtime/Components/RazorComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using Blazor.Routing;
using Blazor.Runtime.Components;
using System.Reflection;
using Blazor.Runtime.Interop;

namespace Blazor.Components
Expand Down Expand Up @@ -56,9 +57,45 @@ protected override void RenderVirtualDom()
// don't have to be marked abstract.
}

private static Dictionary<Type, IEnumerable<MemberInfo>> ParameterMembersCache = new Dictionary<Type, IEnumerable<MemberInfo>>();
private IEnumerable<MemberInfo> GetComponentParameterMembers()
{
if (ParameterMembersCache.ContainsKey(this.GetType()))
{
return ParameterMembersCache[this.GetType()];
}

var decoratedMembers = new List<MemberInfo>();


decoratedMembers.AddRange(this.GetType().GetTypeInfo().DeclaredFields.Where(x => x.GetCustomAttribute(typeof(FromAttributeAttribute), true) != null));
decoratedMembers.AddRange(this.GetType().GetTypeInfo().DeclaredProperties.Where(x => x.GetCustomAttribute(typeof(FromAttributeAttribute),true) != null));

ParameterMembersCache.Add(this.GetType(), decoratedMembers);
return decoratedMembers;
}

protected override void ReceiveParameters(IDictionary<string, object> parameters)
{
// Subclasses may optionally override this
var decoratedMembers = GetComponentParameterMembers();

foreach (var member in decoratedMembers)
{

var attribute = (FromAttributeAttribute)member.GetCustomAttributes().First(x => x.GetType() == typeof(FromAttributeAttribute));
if (!parameters.ContainsKey(attribute.AttributeName) && !attribute.IsOptional)
{
throw new Exception($"Parameter '{attribute.AttributeName}' is required");
}

var parameterValue = parameters[attribute.AttributeName];


if(member is FieldInfo)
((FieldInfo)member).SetValue(this, parameterValue);
else
((PropertyInfo)member).SetValue(this, parameterValue);
}
}

private static Type GetTypeForCompiledRazorFile(string cshtmlFilename)
Expand Down Expand Up @@ -102,7 +139,7 @@ protected VDomAttribute onclick(Action callback)
};
}

protected VDomAttribute onclick(Action<EventInfo> callback)
protected VDomAttribute onclick(Action<VirtualDom.EventInfo> callback)
{
return new VDomAttribute
{
Expand All @@ -120,7 +157,7 @@ protected VDomAttribute onclickAsync(Func<Task> callback)
};
}

protected VDomAttribute onclickAsync(Func<EventInfo, Task> callback)
protected VDomAttribute onclickAsync(Func<VirtualDom.EventInfo, Task> callback)
{
return new VDomAttribute
{
Expand All @@ -129,7 +166,7 @@ protected VDomAttribute onclickAsync(Func<EventInfo, Task> callback)
};
}

protected VDomAttribute onchange(Action<EventInfo> callback)
protected VDomAttribute onchange(Action<VirtualDom.EventInfo> callback)
{
return new VDomAttribute
{
Expand Down