Skip to content

Instantly share code, notes, and snippets.

@emiaj
Last active December 14, 2015 19:29
Show Gist options
  • Select an option

  • Save emiaj/5137444 to your computer and use it in GitHub Desktop.

Select an option

Save emiaj/5137444 to your computer and use it in GitHub Desktop.
public class NestedRemoteRuleGraphActivator : IActivator
{
private readonly ITypeDescriptorCache _properties;
private readonly RemoteRuleGraph _remoteGraph;
private readonly ValidationGraph _validationGraph;
private readonly IRemoteRuleQuery _remotes;
private readonly BehaviorGraph _behaviorGraph;
public NestedRemoteRuleGraphActivator(ITypeDescriptorCache properties, RemoteRuleGraph remoteGraph,
ValidationGraph validationGraph, IRemoteRuleQuery remotes,
BehaviorGraph behaviorGraph)
{
_properties = properties;
_remoteGraph = remoteGraph;
_validationGraph = validationGraph;
_remotes = remotes;
_behaviorGraph = behaviorGraph;
}
public void Activate(IEnumerable<IPackageInfo> packages, IPackageLog log)
{
_behaviorGraph
.Actions()
.Each(FillRules);
}
public void FillRules(ActionCall call)
{
var input = call.InputType();
if (input == null) return;
fillRules(input);
}
private void fillRules(Type type)
{
type = targetType(type);
if (type == null)
{
return;
}
_properties.ForEachProperty(type, property =>
{
var accessor = new SingleProperty(property);
var rules = _validationGraph.Query()
.RulesFor(accessor)
.Where(rule => _remotes.IsRemote(rule));
rules.Each(rule => _remoteGraph.RegisterRule(accessor, rule));
if(property.PropertyType == type)
{
return;
}
fillRules(property.PropertyType);
});
}
private static Type targetType(Type type)
{
if(type == typeof(object))
{
return null;
}
if(type.IsPrimitive)
{
return null;
}
if(type.IsString())
{
return null;
}
if(type.IsDateTime())
{
return null;
}
if (type.IsGenericEnumerable())
{
return targetType(type.FindParameterTypeTo(typeof (IEnumerable<>)));
}
if(type.IsNullable())
{
return targetType(type.GetInnerTypeFromNullable());
}
return type;
}
}
public class RemoteRuleModifier : InputElementModifier
{
protected override void modify(ElementRequest request)
{
var graph = request.Get<RemoteRuleGraph>();
// THIS IS IMPORTANT
var accessor = request.Accessor is SingleProperty ? request.Accessor : new SingleProperty(request.Accessor.InnerProperty);
var rules = graph.RulesFor(accessor);
var data = new RemoteDef
{
rules = rules.Select(x => x.ToHash()).ToArray(),
url = request.Get<IUrlRegistry>().RemoteRule()
};
if (!data.rules.Any())
{
return;
}
request.CurrentTag.Data("remote-rule", data);
}
}
public class RemoteDef
{
public string url { get; set; }
public string[] rules { get; set; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment