Domain

Baked introduces a model generation mechanism to reflect the business domain of a project. The generated model instance can be used directly in layers or in features while configuring configuration targets.

app.Layers.AddDomain();

The generated domain metadata files will be saved to .baked folder at $(ProjectDir) of your application project.

<Target Name="SetCopyComponentDescriptors" BeforeTargets="Generate">
  <PropertyGroup>
    <CopyExportFiles>true</CopyExportFiles>
    ...
  </PropertyGroup>
</Target>

Configuration Targets

This layer provides IDomainTypeCollection and DomainModelBuilderOptions configuration targets for building DomainModel, AttributeDatas and ExportConfigurations for exporting attribute metadata in Generate mode. It also provides DomainServiceCollection configuration target for features to add DomainServiceDescriptor for domain types which then be used to generate an IServiceAdder implementation. The generated IServiceAdder is then used in Start mode for auto registering domain types to service collection. Domain layer also provides an Inspect object to inspect on metadata while DomainModelBuilder builds the domain model through conventions.

Inspect

This feature is still in experimentation and might print false-negative output, meaning it might not capture every change of the inspected attribute.

This target is provided in AddDomainTypes phase. To configure it in a feature;

configurator.Domain.ConfigureInspect(inspect =>
{
    // To inspect an attribute on types
    inspect.TypeAttribute<MyAttribute>(
        when: c => c.Type..., // optional to inspect specific type models
        attribute: ma => ma.Value // optional to inspect just this value
    );

    // To inspect an attribute properties
    inspect.PropertyAttribute<MyAttribute>(
        when: c => c.Property..., // optional to inspect specific property models
        attribute: ma => ma.Value // optional to inspect just this value
    );

    // To inspect an attribute methods
    inspect.MethodAttribute<MyAttribute>(
        when: c => c.Method..., // optional to inspect specific method models
        attribute: ma => ma.Value // optional to inspect just this value
    );

    // To inspect an attribute parameters
    inspect.ParameterAttribute<MyAttribute>(
        when: c => c.Parameter..., // optional to inspect specific parameter models
        attribute: ma => ma.Value // optional to inspect just this value
    );

    // To inspect an attribute any member
    inspect.Attribute<MyAttribute>(
        when: c => c..., // optional to inspect specific members
        attribute: ma => ma.Value // optional to inspect just this value
    );
});

Only one inspect is allowed. If you configure more than one, InvalidOperationException will be thrown

IDomainTypeCollection

This target is provided in AddDomainTypes phase. To configure it in a feature;

configurator.Domain.ConfigureDomainTypeCollection(types =>
{
    ...
});

DomainModelBuilderOptions

This target exposes options for configuring built-in DomainModelBuilder and is provided in AddDomainTypes phase. To configure it in a feature;

configurator.Domain.ConfigureDomainModelBuilder(builder =>
{
    ...
});

DomainServiceCollection

This target is provided in Generate phase and it is used to generate IServiceAdder to add domain services during AddService phase in Start mode. To configure it in a feature;

configurator.Domain.ConfigureDomainServiceCollection((services, domain) =>
{
    // use domain metadata to register services at generate time
    ...
});

AttributeProperties

This target is provided in Generate phase and it is used to configure exported properties for attributes;

configurator.Domain.ConfigureAttributeProperties(properties =>
{
    // configure to output desired attribute properties
    ...
});

ExportConfigurations

This target is provided in Generate phase and it is used to export attribute data of matching types and their members. To configure it in a feature;

configurator.Domain.ConfigureExportConfigurations(exports =>
{
    // configure exports to output desired attribute export files
    ...
});

Phases

This layer introduces following Generate phases to the application it is added;

  • AddDomainTypes: This phase adds an IDomainTypeCollection instance to the application context
  • BuildDomainModel: This phase uses domain types to build and add a DomainModel instance to the application context

To access the domain model from a feature use below extension method;

configurator.UsingDomainModel(domain =>
{
    // use domain metadata to configure any configuration target
    ...
});

Proxifying Entities

It is possible to avoid adding protected virtual and default constructors to classes (such as entity classes) to enable lazy loading and dynamic proxy.

Please add below references to your projects that contain your domain objects (projects that depend only to Baked.Abstractions).

<ItemGroup>
  <PackageReference Include="EmptyConstructor.Fody" PrivateAssets="All" />
  <PackageReference Include="Fody" PrivateAssets="All" />
  <PackageReference Include="Publicize.Fody" PrivateAssets="All" />
  <PackageReference Include="Virtuosity.Fody" PrivateAssets="All" />
</ItemGroup>

Add versions to Directory.Packages.props;

<PackageVersion Include="EmptyConstructor.Fody" Version="..." />
<PackageVersion Include="Fody" Version="..." />
<PackageVersion Include="Publicize.Fody" Version="..." />
<PackageVersion Include="Virtuosity.Fody" Version="..." />

Build your project now. Expect a build fail on your first build after you add fody. This fail adds FodyWeavers.xml to your project. Following builds will success.

<?xml version="1.0" encoding="utf-8"?>
<Weavers GenerateXsd="false">
  <EmptyConstructor />
  <Publicize />
  <Virtuosity />
</Weavers>