The documentation comes from the Markdown files in the source code, so is always up-to-date but available only in English. Enjoy!
At the beginning of a Signum Framework application the Starter
class calls the Start
methods of the different modules used in the applications.
This different Start
methods tipically:
SchemaBuilder.Include
methodThere are of course a lot of other stuff, like registering processes, permission, ResetLazy, etc... but this actions are the bread and butter of most of the Start
methods.
Example:
public static void Start(SchemaBuilder sb)
{
if(sb.NotIncluded(MethodInfo.GetCurrentMethod()))
{
sb.Include<ProjectEntity>();
sb.AddUniqueIndex((ProjectEntity p) => new { p.Name, p.Year });
QueryLogic.Queries.Register(typeof(ProjectEntity), ()=>
from p in Database.Query<ProjectEntity>()
select new
{
Entity = p,
p.Id,
p.Name
});
QueryLogic.Expression.Register((ClientEntity c) => c.Projects())
new Graph<ProjectEntity>.Execute(ProjectOperation.Save)
{
CanBeNew = true,
CanBeModified = true,
Execute = (p, _) => {}
}.Register();
new Graph<ProjectEntity>.Delete(ProjectOperation.Delete)
{
Delete = (p, _) => { p.Delete() }
}.Register();
}
}
With this in mind, the generic method SchemaBuilder.Include
has been expanded to return a FluentInclude<T>
instance:
public class FluentInclude<T> where T : Entity
{
public SchemaBuilder SchemaBuilder { get; private set; }
public Table Table { get; private set; }
}
This class contains methods and extension methods that allow you to register stuff with fewer code.
It doesn't try to cover all the cases, only the common ones, that's why FluentInclude
can be seen as dead-end road.
Other the other side it helps in removing the syntactic noise and leting you concentrate in the interesting stuff, and promotes keeping all the information for a particular entity together.
Example:
public static void Start(SchemaBuilder sb)
{
if(sb.NotIncluded(MethodInfo.GetCurrentMethod()))
{
sb.Include<ProjectEntity>()
.WithUniqueIndex(p => new { p.Name, p.Year })
.WithSave(ProjectOpepration.Save)
.WithDelete(ProjectOpepration.Delete)
.WithQuery(p => new
{
Entity = p,
p.Id,
p.Name
});
}
}
Register an index in the Included entity, tipically a unique index on multiple columns or with a where condition.
public FluentInclude<T> WithUniqueIndex(Expression<Func<T, object>> fields, Expression<Func<T, bool>> where = null)
public FluentInclude<T> WithIndex(Expression<Func<T, object>> fields)
Internally calls SchemaBuilder.AddUniqueIndex
.
Extension method that registers a simple query in QueryLogic.Queeries using typeof(T)
as queryName
, with no filters, joins or column customizations, and just using the provided simpleQuerySelector
as the selector
of the only Select
operator.
public static FluentInclude<T> WithQuery<T, Q>(this FluentInclude<T> fi, Expression<Func<T, Q>> simpleQuerySelector) where T : Entity
Internally calls QueryLogic.Queries.Register
.
Register expressions from another type (F
) that returns an IQueryable<T>
, optionally providing a custom niceName, or null
to keep the method name non-localizable.
public static FluentInclude<T> WithExpressionFrom<T, F>(this FluentInclude<T> fi, Expression<Func<F, IQueryable<T>>> lambdaToMethodOrProperty) where T : Entity
public static FluentInclude<T> WithExpressionFrom<T, F>(this FluentInclude<T> fi, Expression<Func<F, IQueryable<T>>> lambdaToMethodOrProperty, Func<string> niceName) where T : Entity
Note: Given
ProjectEntity
with a property of typeClientEntity
, where is the right place to registerclient.Projects()
expression to navigate the property backwards?. Signum Framework encourages you to register it onProjectLogic
to keepClientLogic
clean of dependencies and more reusable, that's whyWithExpressionFrom
takes an Expression fromF
(aClientEntity
) toIQueryable<T>
(a query ofProjectEntity
).
Internally calls QueryLogic.Queries.Register;
Register trivial implementations of Save
(CanBeNew = true, CanBeModified = true with no body) and Delete (just e.Delete()
in the body).
public static FluentInclude<T> WithSave<T>(this FluentInclude<T> fi, ExecuteSymbol<T> saveOperation) where T : Entity
public static FluentInclude<T> WithDelete<T>(this FluentInclude<T> fi, DeleteSymbol<T> delete) where T : Entity
Internally instantiates a Graph<T>.Execute
/Graph<T>.Delete
and calls the extension method OperationLogic.Register
.
Most of this methods are implemented using extension methods. If you feel the need to remove some code duplication for registering behaviour on a particular entity type, it's a good idea to create your own implementation:
public static WithMyCustomBehaviour(this FluentInclude<T> fi, ...)
© Signum Software. All Rights Reserved.
Powered by Signum Framework