How Dovetail implemented asset extensions from bottles
using DovetailCRM.Core.Extensibility.Assets;
using DovetailCRM.Core.Web.ViewModels;
using DovetailCRM.Web.Controllers.Sites;
using FubuCore;
using FubuMVC.Core.Assets;
using FubuMVC.Core.Registration.Nodes;
namespace DovetailCRM.Packages.HR.Demo.Agent
{
public class ViewSiteAssetExtension : IAssetExtension
{
public bool Matches(BehaviorChain chain)
{
return !chain.FirstCall().Method.Name.Contains("New") && chain.FirstCall().OutputType().CanBeCastTo<EditSiteViewModel>();
}
public void Extend(IAssetRequirements requirements)
{
requirements.Require("viewsite.demo.extension.css");
}
}
}
using FubuMVC.Core.Assets;
using FubuMVC.Core.Registration.Nodes;
namespace DovetailCRM.Core.Extensibility.Assets
{
public interface IAssetExtension
{
bool Matches(BehaviorChain chain);
void Extend(IAssetRequirements requirements);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using FubuMVC.Core;
using FubuMVC.Core.Assets;
using FubuMVC.Core.Behaviors;
using FubuMVC.Core.Registration;
using FubuMVC.Core.Registration.Nodes;
using FubuMVC.Core.Registration.ObjectGraph;
namespace DovetailCRM.Core.Extensibility.Assets
{
public class AssetExtensionPolicy : IConfigurationAction
{
public void Configure(BehaviorGraph graph)
{
graph.Behaviors
.Where(b => b.HasOutputBehavior() && b.ActionOutputType() != (Type) null)
.Each(c => c.Prepend(new AssetExtensionNode(c,typeof(AssetExtensionBehavior))));
}
}
public class AssetExtensionNode : BehaviorNode
{
private readonly BehaviorChain _chain;
private readonly Type _behaviorType;
public AssetExtensionNode(BehaviorChain chain, Type behaviorType)
{
_chain = chain;
_behaviorType = behaviorType;
}
protected override ObjectDef buildObjectDef()
{
var objectDef = new ObjectDef
{
Type = _behaviorType
};
objectDef.DependencyByValue(_chain);
return objectDef;
}
public override BehaviorCategory Category
{
get { return BehaviorCategory.Wrapper;}
}
}
public class AssetExtensionBehavior : BasicBehavior
{
private readonly IAssetRequirements _requirements;
private readonly IEnumerable<IAssetExtension> _extensions;
private readonly BehaviorChain _chain;
public AssetExtensionBehavior(IAssetRequirements requirements, IEnumerable<IAssetExtension> extensions, BehaviorChain chain) : base(PartialBehavior.Executes)
{
_requirements = requirements;
_extensions = extensions;
_chain = chain;
}
protected override FubuMVC.Core.DoNext performInvoke()
{
_extensions.Each(x =>
{
if(x.Matches(_chain)) {x.Extend(_requirements);}
});
return DoNext.Continue;
}
}
}