Creating a component
Key takeaways
Component creation | How to create a component and define its behavior throughout its lifecycle. |
Containerization | How to add a component to a container and execute it. |
Introduction
In this tutorial, we will learn how to create a component and how to assemble a service from it. We will start with a short description of a component’s lifecycle and then we will create a component by defining step-by-step all the elements that compose its lifecycle. Finally, we will assemble a service from it through a container, run it, and see the results.
The lifecycle of a component
A component lifecycle is implemented using interfaces. In this manner, an existing class can be turned into a Pip.Services component (code augmentation). The following diagram summarizes the main states of a component and their respective interfaces
Creating our component
Following the sequence presented in the previous figure, we will create a component and explain each step of its lifecycle.
Step 1 – Creating the component
A component can be seen as a class that has a default constructor. Thus, we will begin by creating a class with a constructor, such as:
class MyComponentA {
private _param1: string = "ABC";
private _param2: number = 123;
private _open: boolean = false;
private _status: string;
// Creates a new instance of the component.
public constructor(){
this._status = "Created";
console.log("MyComponentA has been created.");
}
}
public class MyComponentA
{
private string _param1 = "ABC";
private int _param2 = 123;
private bool _open=false;
private string _status;
// Creates a new instance of the component.
public MyComponentA()
{
_status = "Created";
Console.WriteLine("MyComponentA has been created.");
}
}
type MyComponentA struct {
param1 string
param2 int
open bool
status string
}
func NewMyComponentA() *MyComponentA {
fmt.Println("MyComponentA has been created.")
return &MyComponentA{
param1: "ABC",
param2: 123,
open: false,
status: "Created",
}
}
class MyComponentA {
String _param1 = 'ABC';
int _param2 = 123;
bool _open = false;
String? _status;
// Creates a new instance of the component.
MyComponentA() {
_status = 'Created';
print('MyComponentA has been created.');
}
}
class MyComponentA():
_param1 = 'ABC'
_param2 = 123
_open = False
_status = None
def __init__(self):
"""
Creates a new instance of the component.
"""
self._status = "Created"
print("MyComponentA has been created.")
Step 2 – Configuration
Now that we have a component, we will add configuration capabilities to it. For this, we need to use the Iconfigurable interface and define the configure method. In this method, we will receive a ConfigParams object (key-value map) with the values of the parameters and assign them to our variables.
import { ConfigParams, IConfigurable } from "pip-services3-commons-nodex";
class MyComponentA implements IConfigurable {
private _param1: string = "ABC";
private _param2: number = 123;
private _open: boolean = false;
private _status: string;
// Creates a new instance of the component.
public constructor(){
this._status = "Created";
console.log("MyComponentA has been created.");
}
public configure(config: ConfigParams): void {
this._param1 = config.getAsStringWithDefault("param1", "ABC");
this._param2 = config.getAsIntegerWithDefault("param2", 123);
this._status = "Configured";
console.log("MyComponentA has been configured.");
}
}
using PipServices3.Commons.Config;
using System;
public class MyComponentA: IConfigurable
{
private string _param1 = "ABC";
private int _param2 = 123;
private bool _open=false;
private string _status;
// Creates a new instance of the component.
public MyComponentA()
{
_status = "Created";
Console.WriteLine("MyComponentA has been created.");
}
public void Configure(ConfigParams config)
{
_param1 = config.GetAsStringWithDefault("param1", "ABC");
_param2 = config.GetAsIntegerWithDefault("param2", 123);
_status = "Configured";
Console.WriteLine("MyComponentA has been configured.");
}
}
import (
"fmt"
config "github.com/pip-services3-gox/pip-services3-commons-gox/config"
)
type MyComponentA struct {
config.IConfigurable
param1 string
param2 int
open bool
status string
}
// Creates a new instance of the component.
func NewMyComponentA() *MyComponentA {
fmt.Println("MyComponentA has been created.")
return &MyComponentA{
param1: "ABC",
param2: 123,
open: false,
status: "Created",
}
}
func (c *MyComponentA) Configure(ctx context.Context, config *config.ConfigParams) {
c.param1 = config.GetAsStringWithDefault("param1", "ABC")
c.param2 = config.GetAsIntegerWithDefault("param2", 123)
c.status = "Configured"
fmt.Println("MyComponentA has been configured.")
}
import 'package:pip_services3_commons/pip_services3_commons.dart';
class MyComponentA implements IConfigurable {
String _param1 = 'ABC';
int _param2 = 123;
bool _open = false;
String? _status;
// Creates a new instance of the component.
MyComponentA() {
_status = 'Created';
print('MyComponentA has been created.');
}
@override
void configure(ConfigParams config) {
_param1 = config.getAsStringWithDefault('param1', 'ABC');
_param2 = config.getAsIntegerWithDefault('param2', 123);
_status = 'Configured';
print('MyComponentA has been configured.');
}
}
from pip_services3_commons.config import IConfigurable, ConfigParams
class MyComponentA(IConfigurable):
_param1 = 'ABC'
_param2 = 123
_open = False
_status = None
def __init__(self):
"""
Creates a new instance of the component.
"""
self._status = "Created"
print("MyComponentA has been created.")
def configure(self, config):
self._param1 = config.get_as_string_with_default("param1", 'ABC')
self._param2 = config.get_as_integer_with_default("param2", 123)
self._status = "Configured"
print("MyComponentA has been configured.")
Step 3 – Referencing
After configuring our component, we want to link MyComponentA to another component called MyComponentB. To do this, we need to use the IReferenceable interface. This interface contains the set_references method, which allows us to define references to dependent components. As a component’s locator, we will use a Descriptor object with the connection parameters. Our code will be like this:
import {
ConfigParams, Descriptor, IConfigurable,
IReferenceable, IReferences
} from "pip-services3-commons-nodex";
class MyComponentB {
private _param1: string = "ABC2";
private _param2: number = 456;
private _open: boolean = false;
private _status: string;
// Creates a new instance of the component.
public constructor() {
this._status = "Created";
console.log("MyComponentB has been created.");
}
}
class MyComponentA implements IConfigurable, IReferenceable {
private _param1: string = "ABC";
private _param2: number = 123;
private _open: boolean = false;
private _status: string;
private _anotherComponent: MyComponentB;
// Creates a new instance of the component.
public constructor(){
this._status = "Created";
console.log("MyComponentA has been created.");
}
public setReferences(references: IReferences): void {
this._anotherComponent = references.getOneRequired<MyComponentB>(
new Descriptor("myservice", "mycomponent-b", "*", "*", "1.0")
);
this._status = "Configured";
console.log("MyComponentA's references have been defined.");
}
public configure(config: ConfigParams): void {
this._param1 = config.getAsStringWithDefault("param1", "ABC");
this._param2 = config.getAsIntegerWithDefault("param2", 123);
this._status = "Configured";
console.log("MyComponentA has been configured.");
}
}
using PipServices3.Commons.Config;
using PipServices3.Commons.Refer;
using System;
public class MyComponentB
{
private string _param1 = "ABC2";
private int _param2 = 456;
private bool _open = false;
private string _status;
// Creates a new instance of the component.
public MyComponentB()
{
_status = "Created";
Console.WriteLine("MyComponentB has been created.");
}
}
public class MyComponentA : IReferenceable, IConfigurable
{
private string _param1 = "ABC";
private int _param2 = 123;
private bool _open = false;
private string _status;
private MyComponentB _anotherComponent;
// Creates a new instance of the component.
public MyComponentA()
{
_status = "Created";
Console.WriteLine("MyComponentA has been created.");
}
public void Configure(ConfigParams config)
{
_param1 = config.GetAsStringWithDefault("param1", "ABC");
_param2 = config.GetAsIntegerWithDefault("param2", 123);
_status = "Configured";
Console.WriteLine("MyComponentA has been configured.");
}
public void SetReferences(IReferences references)
{
_anotherComponent = references.GetOneRequired<MyComponentB>(new Descriptor("myservice", "mycomponent-b", "*", "*", "1.0"));
_status = "Configured";
Console.WriteLine("MyComponentA's references have been defined.");
}
}
import (
"fmt"
config "github.com/pip-services3-gox/pip-services3-commons-gox/config"
refer "github.com/pip-services3-gox/pip-services3-commons-gox/refer"
)
type MyComponentB struct {
param1 string
param2 int
open bool
status string
}
type MyComponentA struct {
config.IConfigurable
refer.IReferenceable
param1 string
param2 int
open bool
anotherComponent interface{}
status string
}
// Creates a new instance of the component.
func NewMyComponentB() *MyComponentB {
fmt.Println("MyComponentB has been created.")
return &MyComponentB{
param1: "ABC2",
param2: 456,
open: false,
status: "Created",
}
}
// Creates a new instance of the component.
func NewMyComponentA() *MyComponentA {
fmt.Println("MyComponentA has been created.")
return &MyComponentA{
param1: "ABC",
param2: 123,
open: false,
status: "Created",
}
}
func (c *MyComponentA) Configure(ctx context.Context, config *config.ConfigParams) {
c.param1 = config.GetAsStringWithDefault("param1", "ABC")
c.param2 = config.GetAsIntegerWithDefault("param2", 123)
c.status = "Configured"
fmt.Println("MyComponentA has been configured.")
}
func (c *MyComponentA) SetReferences(ctx context.Context, references refer.IReferences) {
component, err := references.GetOneRequired(
refer.NewDescriptor("myservice", "mycomponent-b", "*", "*", "1.0"),
)
if err == nil {
c.anotherComponent = component.(*MyComponentB)
c.status = "Configured"
fmt.Println("MyComponentA's references have been defined.")
}
}
import 'package:pip_services3_commons/pip_services3_commons.dart';
class MyComponentB {
String _param1 = 'ABC2';
int _param2 = 456;
bool _open = false;
String? _status;
// Creates a new instance of the component.
MyComponentB() {
_status = 'Created';
print('MyComponentB has been created.');
}
}
class MyComponentA implements IConfigurable, IReferenceable {
String _param1 = 'ABC';
int _param2 = 123;
bool _open = false;
String? _status;
MyComponentB? _anotherComponent;
// Creates a new instance of the component.
MyComponentA() {
_status = 'Created';
print('MyComponentA has been created.');
}
@override
void setReferences(IReferences references) {
_anotherComponent = references.getOneRequired<MyComponentB>(
Descriptor('myservice', 'mycomponent-b', '*', '*', '1.0'));
_status = 'Configured';
print("MyComponentA's references have been defined.");
}
@override
void configure(ConfigParams config) {
_param1 = config.getAsStringWithDefault('param1', 'ABC');
_param2 = config.getAsIntegerWithDefault('param2', 123);
_status = 'Configured';
print('MyComponentA has been configured.');
}
}
from pip_services3_commons.config import IConfigurable, ConfigParams
from pip_services3_commons.refer import IReferenceable, IReferences, Descriptor
class MyComponentB():
_param1 = 'ABC2'
_param2 = 456
_opened = False
_status = None
def __init__(self):
"""
Creates a new instance of the component.
"""
self._status = "Created"
print("MyComponentB has been created.")
class MyComponentA(IReferenceable, IConfigurable):
_param1 = 'ABC'
_param2 = 123
_another_component: MyComponentB
_open = False
_status = None
def __init__(self):
"""
Creates a new instance of the component.
"""
self._status = "Created"
print("MyComponentA has been created.")
def configure(self, config):
self._param1 = config.get_as_string_with_default("param1", 'ABC')
self._param2 = config.get_as_integer_with_default("param2", 123)
self._status = "Configured"
print("MyComponentA has been configured.")
def set_references(self, references):
self._another_component = references.get_one_required(
Descriptor("myservice", "mycomponent-b", "*", "*", "1.0")
)
self._status = "Configured"
print("MyComponentA's references have been defined.")
Step 4 – Opening
To help define those components that require opening, PIP.services offers the IOpenable interface. This interface is part of the Commons module and offers two methods: open and isOpen. In our example, we will use the first one to create the code that will open the component, and the second one to verify whether the component is open or not.
Moreover, as the opening of the component marks the start of its usage, we will add an optional parameter called correlation_id. This parameter is used to trace the execution of the component through the call chain. It can be any string, such as “123”.
Now, our code expands to this:
import {
ConfigParams, Descriptor, IConfigurable,
IOpenable, IReferenceable, IReferences
} from "pip-services3-commons-nodex";
class MyComponentB {
// ...
}
class MyComponentA implements IConfigurable, IReferenceable, IOpenable {
private _param1: string = "ABC";
private _param2: number = 123;
private _open: boolean = false;
private _status: string;
private _anotherComponent: MyComponentB;
// Creates a new instance of the component.
public constructor(){
this._status = "Created";
console.log("MyComponentA has been created.");
}
public isOpen(): boolean {
return this._open;
}
public open(correlationId: string): Promise<void> {
this._open = true;
this._status = "Open";
console.log("MyComponentA has been opened.");
return;
}
public setReferences(references: IReferences): void {
this._anotherComponent = references.getOneRequired<MyComponentB>(
new Descriptor("myservice", "mycomponent-b", "*", "*", "1.0")
);
this._status = "Configured";
console.log("MyComponentA's references have been defined.");
}
public configure(config: ConfigParams): void {
this._param1 = config.getAsStringWithDefault("param1", "ABC");
this._param2 = config.getAsIntegerWithDefault("param2", 123);
this._status = "Configured";
console.log("MyComponentA has been configured.");
}
}
using PipServices3.Commons.Config;
using PipServices3.Commons.Refer;
using PipServices3.Commons.Run;
using System;
using System.Threading.Tasks;
public class MyComponentB
{
// ...
}
public class MyComponentA : IReferenceable, IConfigurable, IOpenable
{
private string _param1 = "ABC";
private int _param2 = 123;
private bool _open = false;
private string _status;
private MyComponentB _anotherComponent;
// Creates a new instance of the component.
public MyComponentA()
{
_status = "Created";
Console.WriteLine("MyComponentA has been created.");
}
public void Configure(ConfigParams config)
{
_param1 = config.GetAsStringWithDefault("param1", "ABC");
_param2 = config.GetAsIntegerWithDefault("param2", 123);
_status = "Configured";
Console.WriteLine("MyComponentA has been configured.");
}
public bool IsOpen()
{
return _open;
}
public async Task OpenAsync(string correlationId)
{
_open = true;
_status = "Open";
Console.WriteLine("MyComponentA has been opened.");
}
public void SetReferences(IReferences references)
{
_anotherComponent = references.GetOneRequired<MyComponentB>(new Descriptor("myservice", "mycomponent-b", "*", "*", "1.0"));
_status = "Configured";
Console.WriteLine("MyComponentA's references have been defined.");
}
}
import (
"fmt"
config "github.com/pip-services3-gox/pip-services3-commons-gox/config"
refer "github.com/pip-services3-gox/pip-services3-commons-gox/refer"
run "github.com/pip-services3-gox/pip-services3-commons-gox/run"
)
type MyComponentB struct {
// ...
}
type MyComponentA struct {
config.IConfigurable
refer.IReferenceable
run.IOpenable
param1 string
param2 int
open bool
anotherComponent interface{}
status string
}
func (c *MyComponentA) IsOpen() bool {
return c.open
}
func (c *MyComponentA) Open(ctx context.Context, correlationId string) error {
c.open = true
c.status = "Open"
fmt.Println("MyComponentA has been opened.")
return nil
}
import 'package:pip_services3_commons/pip_services3_commons.dart';
class MyComponentB {
// ...
}
class MyComponentA implements IConfigurable, IReferenceable, IOpenable {
String _param1 = 'ABC';
int _param2 = 123;
bool _open = false;
String? _status;
MyComponentB? _anotherComponent;
// Creates a new instance of the component.
MyComponentA() {
_status = 'Created';
print('MyComponentA has been created.');
}
@override
void setReferences(IReferences references) {
_anotherComponent = references.getOneRequired<MyComponentB>(
Descriptor('myservice', 'mycomponent-b', '*', '*', '1.0'));
_status = 'Configured';
print("MyComponentA's references have been defined.");
}
@override
void configure(ConfigParams config) {
_param1 = config.getAsStringWithDefault('param1', 'ABC');
_param2 = config.getAsIntegerWithDefault('param2', 123);
_status = 'Configured';
print('MyComponentA has been configured.');
}
@override
bool isOpen() {
return _open;
}
@override
Future open(String? correlationId) async {
_open = true;
_status = 'Open';
print('MyComponentA has been opened.');
}
}
from pip_services3_commons.config import IConfigurable, ConfigParams
from pip_services3_commons.refer import IReferenceable, IReferences, Descriptor
class MyComponentB():
# ...
class MyComponentA(IReferenceable, IConfigurable, IOpenable):
_param1 = 'ABC'
_param2 = 123
_another_component: MyComponentB
_open = False
_status = None
# ...
def is_open(self):
return self._open
def open(self, correlation_id):
self._open = True
self._status = "Open"
print("MyComponentA has been opened.")
Step 5 – Execution
We will now define a function that will be used to perform business tasks, and we will call it my_task. In our example, the business task will consist of printing a message and defining a dummy variable.
import {
ConfigParams, Descriptor, IConfigurable,
IOpenable, IReferenceable, IReferences
} from "pip-services3-commons-nodex";
class MyComponentB {
// ...
}
class MyComponentA implements IConfigurable, IReferenceable, IOpenable {
private _param1: string = "ABC";
private _param2: number = 123;
private _open: boolean = false;
private _status: string;
private _anotherComponent: MyComponentB;
public dummyVariable: string;
// ...
public myTask(correlationId: string): void {
console.log("Doing my business task");
this.dummyVariable = "dummy value";
}
}
using PipServices3.Commons.Config;
using PipServices3.Commons.Refer;
using PipServices3.Commons.Run;
using System;
using System.Threading.Tasks;
public class MyComponentB
{
// ...
}
public class MyComponentA : IReferenceable, IConfigurable, IOpenable
{
private string _param1 = "ABC";
private int _param2 = 123;
private bool _open = false;
private string _status;
private MyComponentB _anotherComponent;
public string DummyVariable;
// ...
public void MyTask(string correlationId)
{
Console.WriteLine("Doing my business task");
DummyVariable = "dummy value";
}
}
import (
"fmt"
config "github.com/pip-services3-gox/pip-services3-commons-gox/config"
refer "github.com/pip-services3-gox/pip-services3-commons-gox/refer"
run "github.com/pip-services3-gox/pip-services3-commons-gox/run"
)
type MyComponentB struct {
// ...
}
type MyComponentA struct {
config.IConfigurable
refer.IReferenceable
run.IOpenable
param1 string
param2 int
open bool
anotherComponent interface{}
dummyVariable string
status string
}
// ...
func (c *MyComponentA) MyTask(ctx context.Context, correlationId string) {
fmt.Println("Doing my business task")
c.dummyVariable = "dummy value"
}
import 'package:pip_services3_commons/pip_services3_commons.dart';
class MyComponentB {
// ...
}
class MyComponentA implements IConfigurable, IReferenceable, IOpenable {
String _param1 = 'ABC';
int _param2 = 123;
bool _open = false;
String? _status;
MyComponentB? _anotherComponent;
String? dummyVariable;
// ...
void myTask(String correlationId) {
print('Doing my business task');
dummyVariable = 'dummy value';
}
}
from pip_services3_commons.config import IConfigurable, ConfigParams
from pip_services3_commons.refer import IReferenceable, IReferences, Descriptor
from pip_services3_commons.run import IOpenable
class MyComponentB():
# ...
class MyComponentA(IReferenceable, IConfigurable, IOpenable):
_param1 = 'ABC'
_param2 = 123
_another_component: MyComponentB
_open = False
_status = None
dummy_variable = ""
# ...
def my_task(self, correlation_id):
print("Doing my business task")
dummy_variable = "dummy value"
Step 6 – Closing
As any open component needs to be closed to ensure that the resources used are being freed for other processes, we now need to define our close method. To do this, we use the IClosable interface.
Here, we must note that the IClosable interface was already called by the IOpenable interface in step 4. Thus, we don’t need to explicitly call it now. As our component already has access to this interface, we will define the close method for our class. The code below shows a simplified version of this method.
import {
ConfigParams, Descriptor, IConfigurable,
IOpenable, IReferenceable, IReferences
} from "pip-services3-commons-nodex";
class MyComponentB {
// ...
}
class MyComponentA implements IConfigurable, IReferenceable, IOpenable {
private _param1: string = "ABC";
private _param2: number = 123;
private _open: boolean = false;
private _status: string;
private _anotherComponent: MyComponentB;
public dummyVariable: string;
// ...
public close(correlationId: string): Promise<void> {
this._open = false;
this._status = "Closed";
console.log("MyComponentA has been closed.");
return;
}
}
using PipServices3.Commons.Config;
using PipServices3.Commons.Refer;
using PipServices3.Commons.Run;
using System;
using System.Threading.Tasks;
public class MyComponentB
{
// ...
}
public class MyComponentA : IReferenceable, IConfigurable, IOpenable
{
private string _param1 = "ABC";
private int _param2 = 123;
private bool _open = false;
private string _status;
private MyComponentB _anotherComponent;
public string DummyVariable;
// ...
public async Task CloseAsync(string correlationId)
{
_open = false;
_status = "Closed";
Console.WriteLine("MyComponentA has been closed.");
}
}
import (
"fmt"
config "github.com/pip-services3-gox/pip-services3-commons-gox/config"
refer "github.com/pip-services3-gox/pip-services3-commons-gox/refer"
run "github.com/pip-services3-gox/pip-services3-commons-gox/run"
)
type MyComponentB struct {
// ...
}
type MyComponentA struct {
config.IConfigurable
refer.IReferenceable
run.IOpenable
param1 string
param2 int
open bool
anotherComponent interface{}
dummyVariable string
status string
}
// ...
func (c *MyComponentA) Close(ctx context.Context, correlationId string) error {
c.open = false
c.status = "Closed"
fmt.Println("MyComponentA has been closed.")
return nil
}
import 'package:pip_services3_commons/pip_services3_commons.dart';
class MyComponentB {
// ...
}
class MyComponentA implements IConfigurable, IReferenceable, IOpenable {
String _param1 = 'ABC';
int _param2 = 123;
bool _open = false;
String? _status;
MyComponentB? _anotherComponent;
String? dummyVariable;
// ...
@override
Future close(String? correlationId) async {
_open = false;
_status = 'Closed';
print('MyComponentA has been closed.');
}
}
from pip_services3_commons.config import IConfigurable, ConfigParams
from pip_services3_commons.refer import IReferenceable, IReferences, Descriptor
from pip_services3_commons.run import IOpenable
class MyComponentB():
# ...
class MyComponentA(IReferenceable, IConfigurable, IOpenable):
_param1 = 'ABC'
_param2 = 123
_another_component: MyComponentB
_open = False
_status = None
# ...
def close(self, correlation_id):
self._open = False
self._status = "Closed"
print("MyComponentA has been closed.")
Step 7 – Un-referencing
Once our component has been closed, we need to clear the component’s previously defined references. PIP.services provides the IUnreferenceable interface, which defines the unset_references method. In our example this method will be coded as:
import {
ConfigParams, Descriptor, IConfigurable,
IOpenable, IReferenceable, IReferences
} from "pip-services3-commons-nodex";
class MyComponentB {
// ...
}
class MyComponentA implements IConfigurable, IReferenceable, IOpenable, IUnreferenceable {
private _param1: string = "ABC";
private _param2: number = 123;
private _open: boolean = false;
private _status: string;
private _anotherComponent: MyComponentB;
public dummyVariable: string;
// ...
public unsetReferences(): void {
this._anotherComponent = null;
this._status = "Un-referenced";
console.log("References cleared");
}
}
using PipServices3.Commons.Config;
using PipServices3.Commons.Refer;
using PipServices3.Commons.Run;
using System;
using System.Threading.Tasks;
public class MyComponentB
{
// ...
}
public class MyComponentA : IReferenceable, IConfigurable, IOpenable, IUnreferenceable
{
private string _param1 = "ABC";
private int _param2 = 123;
private bool _open = false;
private string _status;
private MyComponentB _anotherComponent;
public string DummyVariable;
// ...
// Unsets (clears) previously set references to dependent components.
public void UnsetReferences()
{
_anotherComponent = null;
_status = "Un-referenced";
Console.WriteLine("References cleared");
}
}
import (
"fmt"
config "github.com/pip-services3-gox/pip-services3-commons-gox/config"
refer "github.com/pip-services3-gox/pip-services3-commons-gox/refer"
run "github.com/pip-services3-gox/pip-services3-commons-gox/run"
)
type MyComponentB struct {
// ...
}
type MyComponentA struct {
config.IConfigurable
refer.IReferenceable
refer.IUnreferenceable
run.IOpenable
param1 string
param2 int
open bool
anotherComponent interface{}
dummyVariable string
status string
}
// ...
// Unsets (clears) previously set references to dependent components.
func (c *MyComponentA) UnsetReferences(ctx context.Context) {
c.anotherComponent = nil
c.status = "Un-referenced"
fmt.Println("References cleared")
}
import 'package:pip_services3_commons/pip_services3_commons.dart';
class MyComponentB {
// ...
}
class MyComponentA implements IConfigurable, IReferenceable, IOpenable, IUnreferenceable {
String _param1 = 'ABC';
int _param2 = 123;
bool _open = false;
String? _status;
MyComponentB? _anotherComponent;
String? dummyVariable;
// ...
@override
void unsetReferences() {
_anotherComponent = null;
_status = 'Un-referenced';
print('References cleared');
}
}
from pip_services3_commons.config import IConfigurable, ConfigParams
from pip_services3_commons.refer import IReferenceable, IReferences, Descriptor, IUnreferenceable
from pip_services3_commons.run import IOpenable
class MyComponentB():
# ...
class MyComponentA(IReferenceable, IUnreferenceable, IConfigurable, IOpenable):
_param1 = 'ABC'
_param2 = 123
_another_component: MyComponentB
_open = False
_status = None
# ...
def unset_references(self):
"""
Unsets (clears) previously set references to dependent components.
"""
self._another_component = None
self._status = "Un-referenced"
print("References cleared")
Step 8 – Destruction
Finally, to complete the process, we need to dispose of the component. For this, we will use a class destructors or other instruments provided by the languages. Our code will look something like this:
import {
ConfigParams, Descriptor, IConfigurable,
IOpenable, IReferenceable, IReferences
} from "pip-services3-commons-nodex";
class MyComponentB {
// ...
}
class MyComponentA implements IConfigurable, IReferenceable, IOpenable, IUnreferenceable {
private _param1: string = "ABC";
private _param2: number = 123;
private _open: boolean = false;
private _status: string;
private _anotherComponent: MyComponentB;
public dummyVariable: string;
// ...
}
try {
var component = new MyComponentA();
// ...
await component.close(null);
} finally {
console.log("Component destroyed");
}
using PipServices3.Commons.Config;
using PipServices3.Commons.Refer;
using PipServices3.Commons.Run;
using System;
using System.Threading.Tasks;
public class MyComponentB
{
// ...
}
public class MyComponentA : IReferenceable, IConfigurable, IOpenable, IUnreferenceable, IDisposable
{
private string _param1 = "ABC";
private int _param2 = 123;
private bool _open = false;
private string _status;
private MyComponentB _anotherComponent;
public string DummyVariable;
// ...
public void Dispose()
{
Console.WriteLine("Component destroyed");
}
}
import (
"fmt"
config "github.com/pip-services3-gox/pip-services3-commons-gox/config"
refer "github.com/pip-services3-gox/pip-services3-commons-gox/refer"
run "github.com/pip-services3-gox/pip-services3-commons-gox/run"
)
type MyComponentB struct {
// ...
}
type MyComponentA struct {
config.IConfigurable
refer.IReferenceable
refer.IUnreferenceable
run.IOpenable
param1 string
param2 int
open bool
anotherComponent interface{}
dummyVariable string
status string
}
// ...
component := NewMyComponentA()
defer func() {
if !component.IsOpen() {
fmt.Println("Component destroyed")
}
}()
// ...
component.Close(context.Background(), nil)
import 'package:pip_services3_commons/pip_services3_commons.dart';
class MyComponentB {
// ...
}
class MyComponentA implements IConfigurable, IReferenceable, IOpenable, IUnreferenceable {
String _param1 = 'ABC';
int _param2 = 123;
bool _open = false;
String? _status;
MyComponentB? _anotherComponent;
String? dummyVariable;
// ...
}
try {
var component = MyComponentA();
// ...
await component.close(null);
} finally {
print("Component destroyed");
}
from pip_services3_commons.config import IConfigurable, ConfigParams
from pip_services3_commons.refer import IReferenceable, IReferences, Descriptor, IUnreferenceable
from pip_services3_commons.run import IOpenable, ICleanable
class MyComponentB():
# ...
class MyComponentA(IReferenceable, IUnreferenceable, IConfigurable, IOpenable):
_param1 = 'ABC'
_param2 = 123
_another_component: MyComponentB
_open = False
_status = None
# ...
def __del__(self):
print("Component destroyed")
Important note
In this example, we have created a component that accepts configuration parameters, links to other components, opens and executes a process, closes, deletes the links to other components, and destroys itself.
However, the PIP.services toolkit provides many other components that can be used to add extra functionality, such as connectivity to other services, observability, and other types of persistence.
Final code
The complete code for our example is:
import {
ConfigParams, Descriptor, IConfigurable,
IOpenable, IReferenceable, IReferences,
IUnreferenceable
} from "pip-services3-commons-nodex";
class MyComponentB implements IConfigurable, IReferenceable, IOpenable, IUnreferenceable {
private _param1: string = "ABC2";
private _param2: number = 456;
private _open: boolean = false;
private _status: string;
// Creates a new instance of the component.
public constructor() {
this._status = "Created";
console.log("MyComponentB has been created.");
}
public configure(config: ConfigParams): void {
// pass
}
public setReferences(references: IReferences): void {
// pass
}
public isOpen(): boolean {
// pass
return true;
}
public open(correlationId: string): Promise<void> {
// pass
return;
}
public close(correlationId: string): Promise<void> {
// pass
return;
}
public unsetReferences(): void {
// pass
return;
}
}
class MyComponentA implements IConfigurable, IReferenceable, IOpenable, IUnreferenceable {
private _param1: string = "ABC";
private _param2: number = 123;
private _open: boolean = false;
private _status: string;
private _anotherComponent: MyComponentB;
public dummyVariable: string;
// Creates a new instance of the component.
public constructor(){
this._status = "Created";
console.log("MyComponentA has been created.");
}
public isOpen(): boolean {
return this._open;
}
public open(correlationId: string): Promise<void> {
this._open = true;
this._status = "Open";
console.log("MyComponentA has been opened.");
return;
}
public close(correlationId: string): Promise<void> {
this._open = false;
this._status = "Closed";
console.log("MyComponentA has been closed.");
return;
}
public myTask(correlationId: string): void {
console.log("Doing my business task");
this.dummyVariable = "dummy value";
}
public setReferences(references: IReferences): void {
this._anotherComponent = references.getOneRequired<MyComponentB>(
new Descriptor("myservice", "mycomponent-b", "*", "*", "1.0")
);
this._status = "Configured";
console.log("MyComponentA's references have been defined.");
}
public unsetReferences(): void {
this._anotherComponent = null;
this._status = "Un-referenced";
console.log("References cleared");
}
public configure(config: ConfigParams): void {
this._param1 = config.getAsStringWithDefault("param1", "ABC");
this._param2 = config.getAsIntegerWithDefault("param2", 123);
this._status = "Configured";
console.log("MyComponentA has been configured.");
}
}
using PipServices3.Commons.Config;
using PipServices3.Commons.Refer;
using PipServices3.Commons.Run;
using System;
using System.Threading.Tasks;
public class MyComponentB: IReferenceable, IUnreferenceable, IConfigurable, IOpenable, IDisposable
{
private string _param1 = "ABC2";
private int _param2 = 456;
private bool _open = false;
private string _status;
// Creates a new instance of the component.
public MyComponentB()
{
_status = "Created";
Console.WriteLine("MyComponentB has been created.");
}
public async Task CloseAsync(string correlationId)
{
// pass
}
public void Configure(ConfigParams config)
{
// pass
}
public void Dispose()
{
// pass
}
public bool IsOpen()
{
// pass
return true;
}
public async Task OpenAsync(string correlationId)
{
// pass
}
public void SetReferences(IReferences references)
{
// pass
}
public void UnsetReferences()
{
// pass
}
}
public class MyComponentA : IReferenceable, IConfigurable, IOpenable, IUnreferenceable, IDisposable
{
private string _param1 = "ABC";
private int _param2 = 123;
private bool _open = false;
private string _status;
private MyComponentB _anotherComponent;
public string DummyVariable;
// Creates a new instance of the component.
public MyComponentA()
{
_status = "Created";
Console.WriteLine("MyComponentA has been created.");
}
public void Configure(ConfigParams config)
{
_param1 = config.GetAsStringWithDefault("param1", "ABC");
_param2 = config.GetAsIntegerWithDefault("param2", 123);
_status = "Configured";
Console.WriteLine("MyComponentA has been configured.");
}
public bool IsOpen()
{
return _open;
}
public async Task OpenAsync(string correlationId)
{
_open = true;
_status = "Open";
Console.WriteLine("MyComponentA has been opened.");
}
public async Task CloseAsync(string correlationId)
{
_open = false;
_status = "Closed";
Console.WriteLine("MyComponentA has been closed.");
}
public void MyTask(string correlationId)
{
Console.WriteLine("Doing my business task");
DummyVariable = "dummy value";
}
public void SetReferences(IReferences references)
{
_anotherComponent = references.GetOneRequired<MyComponentB>(new Descriptor("myservice", "mycomponent-b", "*", "*", "1.0"));
_status = "Configured";
Console.WriteLine("MyComponentA's references have been defined.");
}
// Unsets (clears) previously set references to dependent components.
public void UnsetReferences()
{
_anotherComponent = null;
_status = "Un-referenced";
Console.WriteLine("References cleared");
}
public void Dispose()
{
Console.WriteLine("Component destroyed");
}
}
import (
"fmt"
config "github.com/pip-services3-gox/pip-services3-commons-gox/config"
refer "github.com/pip-services3-gox/pip-services3-commons-gox/refer"
run "github.com/pip-services3-gox/pip-services3-commons-gox/run"
)
type MyComponentB struct {
param1 string
param2 int
open bool
status string
}
// Creates a new instance of the component.
func NewMyComponentB() *MyComponentB {
fmt.Println("MyComponentB has been created.")
return &MyComponentB{
param1: "ABC2",
param2: 456,
open: false,
status: "Created",
}
}
func (c *MyComponentB) Configure(ctx context.Context, config *config.ConfigParams) {
// pass
}
func (c *MyComponentB) SetReferences(ctx context.Context, references refer.IReferences) {
// pass
}
func (c *MyComponentB) IsOpen() bool {
// pass
return true
}
func (c *MyComponentB) Open(ctx context.Context, correlationId string) error {
// pass
return nil
}
func (c *MyComponentB) Close(ctx context.Context, correlationId string) error {
// pass
return nil
}
// Unsets (clears) previously set references to dependent components.
func (c *MyComponentB) UnsetReferences(ctx context.Context) {
// pass
}
func (c *MyComponentB) MyTask(ctx context.Context, correlationId string) {
// pass
}
type MyComponentA struct {
config.IConfigurable
refer.IReferenceable
refer.IUnreferenceable
run.IOpenable
param1 string
param2 int
open bool
anotherComponent interface{}
dummyVariable string
status string
}
// Creates a new instance of the component.
func NewMyComponentA() *MyComponentA {
fmt.Println("MyComponentA has been created.")
return &MyComponentA{
param1: "ABC",
param2: 123,
open: false,
status: "Created",
}
}
func (c *MyComponentA) Configure(ctx context.Context, config *config.ConfigParams) {
c.param1 = config.GetAsStringWithDefault("param1", "ABC")
c.param2 = config.GetAsIntegerWithDefault("param2", 123)
c.status = "Configured"
fmt.Println("MyComponentA has been configured.")
}
func (c *MyComponentA) SetReferences(ctx context.Context, references refer.IReferences) {
component, err := references.GetOneRequired(
refer.NewDescriptor("myservice", "mycomponent-b", "*", "*", "1.0"),
)
if err == nil {
c.anotherComponent = component.(*MyComponentB)
c.status = "Configured"
fmt.Println("MyComponentA's references have been defined.")
}
}
func (c *MyComponentA) IsOpen() bool {
return c.open
}
func (c *MyComponentA) Open(ctx context.Context, correlationId string) error {
c.open = true
c.status = "Open"
fmt.Println("MyComponentA has been opened.")
return nil
}
func (c *MyComponentA) Close(ctx context.Context, correlationId string) error {
c.open = false
c.status = "Closed"
fmt.Println("MyComponentA has been closed.")
return nil
}
// Unsets (clears) previously set references to dependent components.
func (c *MyComponentA) UnsetReferences(ctx context.Context) {
c.anotherComponent = nil
c.status = "Un-referenced"
fmt.Println("References cleared")
}
func (c *MyComponentA) MyTask(ctx context.Context, correlationId string) {
fmt.Println("Doing my business task")
c.dummyVariable = "dummy value"
}
import 'package:pip_services3_commons/pip_services3_commons.dart';
class MyComponentB
implements IConfigurable, IReferenceable, IOpenable, IUnreferenceable {
String _param1 = 'ABC2';
int _param2 = 456;
bool _open = false;
String? _status;
// Creates a new instance of the component.
MyComponentB() {
_status = 'Created';
print('MyComponentB has been created.');
}
@override
Future close(String? correlationId) async {
// pass
}
@override
void configure(ConfigParams config) {
// pass
}
@override
bool isOpen() {
// pass
return true;
}
@override
Future open(String? correlationId) async {
// pass
}
@override
void setReferences(IReferences references) {
// pass
}
@override
void unsetReferences() {
// pass
}
}
class MyComponentA
implements IConfigurable, IReferenceable, IOpenable, IUnreferenceable {
String _param1 = 'ABC';
int _param2 = 123;
bool _open = false;
String? _status;
MyComponentB? _anotherComponent;
String? dummyVariable;
// Creates a new instance of the component.
MyComponentA() {
_status = 'Created';
print('MyComponentA has been created.');
}
@override
void setReferences(IReferences references) {
_anotherComponent = references.getOneRequired<MyComponentB>(
Descriptor('myservice', 'mycomponent-b', '*', '*', '1.0'));
_status = 'Configured';
print("MyComponentA's references have been defined.");
}
@override
void configure(ConfigParams config) {
_param1 = config.getAsStringWithDefault('param1', 'ABC');
_param2 = config.getAsIntegerWithDefault('param2', 123);
_status = 'Configured';
print('MyComponentA has been configured.');
}
@override
bool isOpen() {
return _open;
}
@override
Future open(String? correlationId) async {
_open = true;
_status = 'Open';
print('MyComponentA has been opened.');
}
@override
Future close(String? correlationId) async {
_open = false;
_status = 'Closed';
print('MyComponentA has been closed.');
}
void myTask(String correlationId) {
print('Doing my business task');
dummyVariable = 'dummy value';
}
@override
void unsetReferences() {
_anotherComponent = null;
_status = 'Un-referenced';
print('References cleared');
}
}
from pip_services3_commons.config import IConfigurable, ConfigParams
from pip_services3_commons.refer import IReferenceable, IReferences, Descriptor, IUnreferenceable
from pip_services3_commons.run import IOpenable
class MyComponentB(IReferenceable, IUnreferenceable, IConfigurable, IOpenable):
_param1 = 'ABC2'
_param2 = 456
_opened = False
def __init__(self):
"""
Creates a new instance of the component.
"""
self._status = "Created"
print("MyComponentB has been created.")
def configure(self, config):
self._param1 = config.get_as_string_with_default("param1", self._param1)
self._param2 = config.get_as_integer_with_default("param2", self._param2)
print("MyComponentB has been configured.")
def set_references(self, references):
pass
def is_open(self):
pass
def open(self, correlation_id):
pass
def close(self, correlation_id):
pass
def my_task(self, correlation_id):
pass
def unset_references(self):
pass
def __del__(self):
pass
class MyComponentA(IReferenceable, IUnreferenceable, IConfigurable, IOpenable):
_param1 = 'ABC'
_param2 = 123
_another_component: MyComponentB
_open = False
_status = None
def __init__(self):
"""
Creates a new instance of the component.
"""
self._status = "Created"
print("MyComponentA has been created.")
def configure(self, config):
self._param1 = config.get_as_string_with_default("param1", 'ABC')
self._param2 = config.get_as_integer_with_default("param2", 123)
self._status = "Configured"
print("MyComponentA has been configured.")
def set_references(self, references):
self._another_component = references.get_one_required(
Descriptor("myservice", "mycomponent-b", "*", "*", "1.0")
)
self._status = "Configured"
print("MyComponentA's references have been defined.")
def is_open(self):
return self._open
def open(self, correlation_id):
self._open = True
self._status = "Open"
print("MyComponentA has been opened.")
def close(self, correlation_id):
self._opened = False
self._status = "Closed"
print("MyComponentA has been closed.")
def my_task(self, correlation_id):
print("Doing my business task")
dummy_variable = "dummy value"
def unset_references(self):
"""
Unsets (clears) previously set references to dependent components.
"""
self._another_component = None
self._status = "Un-referenced"
print("References cleared")
def __del__(self):
print("Component destroyed")
Executing our code
Now, we can execute our code step-by-step. Our program will look something like this:
import 'package:pip_services3_commons/pip_services3_commons.dart';
void main(List<String> arguments) async {
try {
// Step 1 - Creation
var myComponentA = MyComponentA();
var myComponentB = MyComponentB();
// Step 2 - Configure the component
myComponentA
.configure(ConfigParams.fromTuples(['param1', 'XYZ', 'param2', '987']));
// Step 3 - Referencing
// Set references to the component
myComponentA.setReferences(References.fromTuples([
Descriptor('myservice', 'mycomponent-b', 'default', 'default', '1.0'),
myComponentB
]));
// Step 4 - Openning
await myComponentA.open('123');
// Step 5 - Execution
myComponentA.myTask('123');
// Step 6 - Closing
await myComponentA.close('123');
// Step 7 - Un-referencing
myComponentA.unsetReferences();
} finally {
// Step 8 - Destruction
print('Component destroyed');
}
}
using PipServices3.Commons.Config;
using PipServices3.Commons.Refer;
static void Main(string[] args)
{
// Step 1 - Creation
var myComponentA = new MyComponentA();
var myComponentB = new MyComponentB();
// Step 2 - Configure the component
myComponentA.Configure(ConfigParams.FromTuples(
"param1", "XYZ",
"param2", "987"
));
// Step 3 - Referencing
// Set references to the component
myComponentA.SetReferences(References.FromTuples(
new Descriptor("myservice", "mycomponent-b", "default", "default", "1.0"), myComponentB
));
// Step 4 - Openning
myComponentA.OpenAsync("123").Wait();
// Step 5 - Execution
myComponentA.MyTask("123");
// Step 6 - Closing
myComponentA.CloseAsync("123").Wait();
// Step 7 - Un-referencing
myComponentA.UnsetReferences();
// Step 8 - Destruction
myComponentA.Dispose();
}
import (
"fmt"
config "github.com/pip-services3-gox/pip-services3-commons-gox/config"
refer "github.com/pip-services3-gox/pip-services3-commons-gox/refer"
)
func main() {
// Step 1 - Creation
myComponentA := NewMyComponentA()
myComponentB := NewMyComponentB()
// Step 2 - Configure the component
myComponentA.Configure(ctx context.Context, config.NewConfigParamsFromTuples(
"param1", "XYZ",
"param2", "987",
))
// Step 3 - Referencing
// Set references to the component
myComponentA.SetReferences(ctx context.Context, refer.NewReferencesFromTuples(
refer.NewDescriptor("myservice", "mycomponent-b", "default", "default", "1.0"), myComponentB,
))
// Step 4 - Openning
myComponentA.Open(ctx context.Context, "123")
// Step 5 - Execution
myComponentA.MyTask(ctx context.Context, "123")
// Step 6 - Closing
myComponentA.Close(ctx context.Context, "123")
// Step 7 - Un-referencing
myComponentA.UnsetReferences(ctx context.Context)
// Step 8 - Destruction
defer func() {
if !NewMyComponentA().IsOpen() {
fmt.Println("Component destroyed")
}
}()
}
import {
ConfigParams, Descriptor, IConfigurable,
IOpenable, IReferenceable, IReferences,
IUnreferenceable, References
} from "pip-services3-commons-nodex";
async function main() {
try {
// Step 1 - Creation
var myComponentA = new MyComponentA();
var myComponentB = new MyComponentB();
// Step 2 - Configure the component
myComponentA.configure(ConfigParams.fromTuples(
"param1", "XYZ",
"param2", "987"
));
// Step 3 - Referencing
// Set references to the component
myComponentA.setReferences(References.fromTuples(
new Descriptor("myservice", "mycomponent-b", "default", "default", "1.0"), myComponentB
));
// Step 4 - Openning
await myComponentA.open("123");
// Step 5 - Execution
myComponentA.myTask("123");
// Step 6 - Closing
await myComponentA.close("123");
// Step 7 - Un-referencing
myComponentA.unsetReferences();
} finally {
// Step 8 - Destruction
console.log("Component destroyed")
}
}
from pip_services3_commons.config import IConfigurable, ConfigParams
from pip_services3_commons.refer import References, Descriptor
# Step 1 - Creation
my_component_A = MyComponentA()
my_component_B = MyComponentB()
# Step 2 - Configure the component
my_component_A.configure(ConfigParams.from_tuples(
'param1', 'XYZ',
'param2', '987'
))
# Step 3 - Referencing
# Set references to the component
my_component_A.set_references(References.from_tuples(
Descriptor("myservice", "mycomponent-b", "default", "default", "1.0"), my_component_B
))
# Step 4 - Openning
my_component_A.open("123")
# Step 5 - Execution
my_component_A.my_task("123")
# Step 6 - Closing
my_component_A.close("123")
# Step 7 - Un-referencing
my_component_A.unset_references()
# Step 8 - Destruction
my_component_A.__del__()
Which, after running, results in the following output:
Assembling a service from our component
At present, we have a component that is capable of connecting to another component and can execute some actions defined by us. This component is ready for use. However, running it step-by-step can be laborious and inefficient.
To solve this problem, we can use a container. PIP.Services offers the ProcessContainer, which is an Inversion of control (IoC) container that runs as a system process.
As this container uses a factory to create the contained components, we will create one via the Factory class. Once again, we will use Descriptor objects to locate each component, and we will use the method register_as_type to register the component in our factory. This method requires the locator and the component’s type. Our updated code is:
import { Factory } from "pip-services3-components-nodex";
class MyClassFactory extends Factory {
public constructor() {
super();
var ComponentADescriptor = new Descriptor("myservice", "mycomponentA", "default", "*", "1.0");
var ComponentBDescriptor = new Descriptor("myservice", "mycomponent-b", "default", "*", "1.0");
this.registerAsType(ComponentADescriptor, MyComponentA);
this.registerAsType(ComponentBDescriptor, MyComponentB);
}
}
using PipServices3.Components.Build;
// Creating a factory
public class MyClassFactory: Factory
{
public MyClassFactory(): base()
{
var ComponentADescriptor = new Descriptor("myservice", "mycomponentA", "default", "*", "1.0");
var ComponentBDescriptor = new Descriptor("myservice", "mycomponent-b", "default", "*", "1.0");
RegisterAsType(ComponentADescriptor, typeof(MyComponentA));
RegisterAsType(ComponentBDescriptor, typeof(MyComponentB));
}
}
import (
build "github.com/pip-services3-gox/pip-services3-components-gox/build"
)
// Creating a factory
type MyClassFactory struct {
*build.Factory
}
func NewMyClassFactory() *MyClassFactory {
c := MyClassFactory{}
c.Factory = build.NewFactory()
ComponentADescriptor := refer.NewDescriptor("myservice", "mycomponentA", "default", "*", "1.0")
ComponentBDescriptor := refer.NewDescriptor("myservice", "mycomponent-b", "default", "*", "1.0")
c.RegisterType(ComponentADescriptor, NewMyComponentA)
c.RegisterType(ComponentBDescriptor, NewMyComponentB)
return &c
}
import 'package:pip_services3_components/pip_services3_components.dart';
class MyClassFactory extends Factory {
MyClassFactory() : super() {
var ComponentADescriptor =
Descriptor('myservice', 'mycomponentA', 'default', '*', '1.0');
var ComponentBDescriptor =
Descriptor('myservice', 'mycomponent-b', 'default', '*', '1.0');
registerAsType(ComponentADescriptor, MyComponentA);
registerAsType(ComponentBDescriptor, MyComponentB);
}
}
# Creating a factory
from pip_services3_components.build import Factory
class MyClassFactory(Factory):
def __init__(self):
super(MyClassesFactory, self).__init__()
ComponentADescriptor = Descriptor("myservice", "mycomponentA", "default", "*", "1.0")
ComponentBDescriptor = Descriptor("myservice", "mycomponent-b", "default", "*", "1.0")
self.register_as_type(ComponentADescriptor, MyComponentA)
self.register_as_type(ComponentBDescriptor, MyComponentB)
Once our factory is ready, we can proceed to create our container. First, we will create a class named MyProcess as a subclass of ProcessContainer. Inside this class, we will state the path to our configuration file, and add our previously created factory.
import { ProcessContainer } from "pip-services3-container-nodex";
// Creating a process container
class MyProcess extends ProcessContainer {
public constructor() {
super("myservice", "My service running as a process");
this._configPath = './config.yaml';
this._factories.add(new MyClassFactory());
}
}
using PipServices3.Container;
// Creating a process container
public class MyProcess: ProcessContainer
{
public MyProcess(): base("myservice", "My service running as a process")
{
_configPath = "../../../../config/config.yml";
_factories.Add(new MyClassFactory());
}
}
// Creating a process container
type MyProcess struct {
*container.ProcessContainer
}
func NewMyProcess() *MyProcess {
c := &MyProcess{
ProcessContainer: container.NewProcessContainer("myservice", "My service running as a process"),
}
c.SetConfigPath("./config.yaml")
c.AddFactory(NewMyClassFactory())
return c
}
import 'package:pip_services3_container/pip_services3_container.dart';
// Creating a process container
class MyProcess extends ProcessContainer {
MyProcess() : super('myservice', 'My service running as a process') {
configPath = './config.yaml';
factories.add(MyClassFactory());
}
}
# Creating a process container
from pip_services3_container import ProcessContainer
class MyProcess(ProcessContainer):
def __init__(self):
super(MyProcess, self).__init__('myservice', 'My service running as a process')
self._config_path = 'E:\\config2.yaml'
self._factories.add(MyClassFactory())
Our configuration file must declare our component’s descriptor and the values we want to assign to our parameters. We will use YAML syntax for this purpose. Below is an example of this type of declaration.
Using our component
We have a service, and to use it, we just need to create an instance of our container and call the run method.
let MyProcess = require('./obj/component').MyProcess;
try {
let proc = new MyProcess();
proc.run(process.argv);
} catch (ex) {
console.error(ex);
}
class Program
{
static void Main(string[] args)
{
try
{
var task = (new MyProcess()).RunAsync(args);
task.Wait();
}
catch (Exception ex)
{
Console.Error.WriteLine(ex);
}
}
}
func main() {
runner := NewMyProcess()
runner.Run(os.Environ())
}
void main(List<String> arguments) async {
try {
var proc = MyProcess();
proc.run(arguments);
} catch (ex) {
print(ex);
}
}
if __name__ == '__main__':
runner = MyProcess()
print("run")
try:
runner.run()
except Exception as ex:
print(ex)
After running our service, we should see the following output, which confirms that components A and B have been created and linked:
As our component is complete and fully functional, this step marks the end of our task.
Wrapping up
In this tutorial, we have created a component, defined all the necessary methods for managing its lifecycle, and assembled a service from it. We also saw that containers offer a more efficient way to run components.
More complex components will follow a similar structure, but with added functionality. For example, we can add things like different forms of persistence, connectivity to other services, observability, caching, and more. You can find an example of this in the Data Microservice tutorial.