Skip to main content

Sharing configurationsโ€‹

It can be quite handy to share configurations between different projects. This can be done by creating a separate package that contains the configuration and then installing it in the projects that need it.

Clawject provides a way to share @Configuration and @ClawjectApplication classes between different projects by generating metadata field on a target class type declaration.

To make this work, you should add metadata transformer to your compilation process.

Exampleโ€‹

Let's say we have a FooConfiguration class that you want to share between different projects:

shared-package/foo-configuration.ts
import { Bean, Configuration } from '@clawject/di';
import { Foo } from './Foo';

@Configuration
export class FooConfiguration {
foo = Bean(Foo);
}

If you have added the metadata transformer to your compilation process, compiled declaration file will contain a #_clawject_metadata field on the FooConfiguration class type declaration and a ClawjectMetadata namespaces that contains needed metadata for clawject to work with added to the .d.ts file.

tip
  • #_clawject_metadata field is added only to the declaration file, and not exists in runtime. Typescript will not allow you to access it because it is a private field of class.
  • ClawjectMetadata namespace is added to the .d.ts file to provide needed metadata for clawject to work with, it contains only types and not accessible outside the .d.ts file.
  • You don't need to worry about names collision, Clawject will generate unique names.
shared-package/dist/foo-configuration.d.ts
import { Foo } from './Foo';
export declare class FooConfiguration {
foo: import("@clawject/di").BeanConstructorFactory<Foo, typeof Foo>;
#_clawject_metadata: ClawjectMetadata_1.FooConfiguration_1;
}

declare namespace ClawjectMetadata_1 {
export type FooConfiguration_1 = {
kind: 1;
version: 1;
external: null;
beans: [
{
kind: 2;
primary: false;
external: null;
qualifier: null;
nestedProperty: null;
classPropertyName: "foo";
}
];
imports: [];
};
}

Now you can install the shared-package in your project and import the FooConfiguration class into your @ClawjectApplication class, and request Foo bean that is defined in the FooConfiguration class:

app.ts
import { ClawjectApplication, Import, PostConstruct } from '@clawject/di';
import { Foo, FooConfiguration } from 'shared-package';

@ClawjectApplication
class App {
fooConfiguration = Import(FooConfiguration);

@PostConstruct
/* Foo bean is injected here */
init(foo: Foo) {
/* ... */
}
}

That's it! Now you can share configurations between different projects.