ndsdk-cli 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ndsdk/__init__.py +3 -0
- ndsdk/config_normalizer.py +306 -0
- ndsdk/generators/__init__.py +8 -0
- ndsdk/generators/base.py +93 -0
- ndsdk/generators/engine.py +715 -0
- ndsdk/main.py +536 -0
- ndsdk/naming.py +112 -0
- ndsdk/packages/client_provider/Program.fragment.cs.j2 +1 -0
- ndsdk/packages/client_provider/appsettings.fragment.json.j2 +14 -0
- ndsdk/packages/client_provider/package.yaml +13 -0
- ndsdk/packages/db_provider/Program.fragment.cs.j2 +3 -0
- ndsdk/packages/db_provider/appsettings.fragment.json.j2 +30 -0
- ndsdk/packages/db_provider/package.yaml +123 -0
- ndsdk/packages/exception_handling/Program.app.fragment.cs.j2 +1 -0
- ndsdk/packages/exception_handling/Program.fragment.cs.j2 +1 -0
- ndsdk/packages/exception_handling/package.yaml +7 -0
- ndsdk/packages/file_storage_azure/Program.fragment.cs.j2 +1 -0
- ndsdk/packages/file_storage_azure/appsettings.fragment.json.j2 +6 -0
- ndsdk/packages/file_storage_azure/package.yaml +9 -0
- ndsdk/packages/observability/Program.fragment.cs.j2 +2 -0
- ndsdk/packages/observability/appsettings.fragment.json.j2 +39 -0
- ndsdk/packages/observability/package.yaml +16 -0
- ndsdk/registry.py +192 -0
- ndsdk/templates/_common/BO.cs.j2 +10 -0
- ndsdk/templates/_common/Controller.cs.j2 +131 -0
- ndsdk/templates/_common/DbProviderBase.cs.j2 +26 -0
- ndsdk/templates/_common/Dockerfile.j2 +15 -0
- ndsdk/templates/_common/Dto.cs.j2 +16 -0
- ndsdk/templates/_common/Entity.cs.j2 +16 -0
- ndsdk/templates/_common/IService.cs.j2 +25 -0
- ndsdk/templates/_common/Model.cs.j2 +16 -0
- ndsdk/templates/_common/Provider.cs.j2 +151 -0
- ndsdk/templates/_common/ProviderBase.cs.j2 +10 -0
- ndsdk/templates/_common/Service.cs.j2 +49 -0
- ndsdk/templates/_common/ServiceManager.cs.j2 +28 -0
- ndsdk/templates/_common/Solution.sln.j2 +22 -0
- ndsdk/templates/_common/_csproj_refs.inc.j2 +14 -0
- ndsdk/templates/_common/launchSettings.json.j2 +17 -0
- ndsdk/templates/microservice/clean/Api.csproj.j2 +12 -0
- ndsdk/templates/microservice/clean/ClassLib.csproj.j2 +11 -0
- ndsdk/templates/microservice/clean/Program.cs.j2 +35 -0
- ndsdk/templates/microservice/clean/layout.yaml +64 -0
- ndsdk/templates/microservice/layered/Program.cs.j2 +61 -0
- ndsdk/templates/microservice/layered/Project.csproj.j2 +12 -0
- ndsdk/templates/microservice/layered/layout.yaml +41 -0
- ndsdk/validators.py +213 -0
- ndsdk_cli-1.0.0.dist-info/METADATA +11 -0
- ndsdk_cli-1.0.0.dist-info/RECORD +51 -0
- ndsdk_cli-1.0.0.dist-info/WHEEL +5 -0
- ndsdk_cli-1.0.0.dist-info/entry_points.txt +2 -0
- ndsdk_cli-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// -----------------------------------------------------------------------------
|
|
2
|
+
// AUTO-GENERATED BY ND-SDK CLI — DO NOT EDIT.
|
|
3
|
+
// Interface for {{ service_name }}. Implementation is yours to write.
|
|
4
|
+
// -----------------------------------------------------------------------------
|
|
5
|
+
using Microsoft.Extensions.Configuration;
|
|
6
|
+
{% if dtos %}
|
|
7
|
+
using {{ ns.dtos }};
|
|
8
|
+
{% endif %}
|
|
9
|
+
{% if models %}
|
|
10
|
+
using {{ ns.models }};
|
|
11
|
+
{% endif %}
|
|
12
|
+
|
|
13
|
+
namespace {{ ns.service }}
|
|
14
|
+
{
|
|
15
|
+
public interface I{{ service_name }}Service{% if use_service_locator %} : IService{% endif %}
|
|
16
|
+
|
|
17
|
+
{
|
|
18
|
+
{% for ep in business_endpoints %}
|
|
19
|
+
{% set method = ep.service_method | default(ep.name | pascal_case) %}
|
|
20
|
+
{% set request_type = ep.request_dto | default(ep.request_model | default('')) %}
|
|
21
|
+
{% set response_type = ep.response_dto | default(ep.response_model | default('object')) %}
|
|
22
|
+
{{ response_type }} {{ method }}({% if request_type %}{{ request_type }} input, {% endif %}IConfiguration configuration);
|
|
23
|
+
{% endfor %}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Generated by ND-SDK CLI from config. Internal/domain model.
|
|
2
|
+
using System.Text.Json.Serialization;
|
|
3
|
+
|
|
4
|
+
namespace {{ ns.models }}
|
|
5
|
+
{
|
|
6
|
+
public class {{ model.name }}
|
|
7
|
+
{
|
|
8
|
+
{% for f in model.fields | default([]) %}
|
|
9
|
+
{% if f.json_name | default('') %}
|
|
10
|
+
[JsonPropertyName("{{ f.json_name }}")]
|
|
11
|
+
{% endif %}
|
|
12
|
+
public {{ f.type | csharp_type }}{% if f.nullable | default(false) %}?{% endif %} {{ f.name | pascal_case }} { get; set; }{% if f.default is defined %} = {{ f.default }};{% endif %}
|
|
13
|
+
|
|
14
|
+
{% endfor %}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
{% if provider.is_db and provider.has_methods %}
|
|
2
|
+
// -----------------------------------------------------------------------------
|
|
3
|
+
// Generated by ND-SDK CLI as a SCAFFOLD. This file is yours — finish the TODO
|
|
4
|
+
// bodies. It is written once and NOT overwritten on regenerate (use
|
|
5
|
+
// `ndsdk generate --layer provider --service {{ service_name }} --force` to
|
|
6
|
+
// re-scaffold after changing the provider config).
|
|
7
|
+
// -----------------------------------------------------------------------------
|
|
8
|
+
using System;
|
|
9
|
+
using System.Collections.Generic;
|
|
10
|
+
using Microsoft.Extensions.Configuration;
|
|
11
|
+
using Newtonsoft.Json;
|
|
12
|
+
using DataAccessLayer.Enums;
|
|
13
|
+
{% if provider.has_relational and db_settings.adapter is defined and db_settings.adapter.extended_context_using %}
|
|
14
|
+
using {{ db_settings.adapter.extended_context_using }};
|
|
15
|
+
{% endif %}
|
|
16
|
+
{% if db_settings.facade_namespace | default('') %}
|
|
17
|
+
using {{ db_settings.facade_namespace }};
|
|
18
|
+
{% endif %}
|
|
19
|
+
{% if db_settings.types_namespace | default('') %}
|
|
20
|
+
using {{ db_settings.types_namespace }};
|
|
21
|
+
{% endif %}
|
|
22
|
+
{% if entities %}
|
|
23
|
+
using {{ ns.entities }};
|
|
24
|
+
{% endif %}
|
|
25
|
+
|
|
26
|
+
namespace {{ ns.provider }}
|
|
27
|
+
{
|
|
28
|
+
public class {{ provider.name }} : {{ provider.name }}Base
|
|
29
|
+
{
|
|
30
|
+
private readonly {{ db_settings.facade_type | default('DbExternalizationFacade') }} _dbFacade;
|
|
31
|
+
|
|
32
|
+
public {{ provider.name }}({{ db_settings.facade_type | default('DbExternalizationFacade') }} dbFacade)
|
|
33
|
+
{
|
|
34
|
+
_dbFacade = dbFacade;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
{% for m in provider.methods %}
|
|
38
|
+
{% set adapter = db_settings.adapter | default({}) %}
|
|
39
|
+
{% if m.relational %}
|
|
40
|
+
{# ---------------------- relational stored procedure ---------------------- #}
|
|
41
|
+
{% set out_params = m.parameters | selectattr('direction', 'equalto', 'out') | list %}
|
|
42
|
+
{% set cursor_params = m.parameters | selectattr('direction', 'equalto', 'cursor') | list %}
|
|
43
|
+
{% set sized = out_params | selectattr('size', 'defined') | list %}
|
|
44
|
+
public override {{ m.return_type_cs }} {{ m.name | pascal_case }}({% if m.entity is defined and m.entity %}{{ m.entity }} input, {% endif %}IConfiguration configuration)
|
|
45
|
+
{
|
|
46
|
+
var inputParameters = new Dictionary<string, object>
|
|
47
|
+
{
|
|
48
|
+
{% for p in m.parameters if (p.direction | default('in')) == 'in' %}
|
|
49
|
+
{ "{{ p.name }}", {% if p.entity_field is defined %}(object?)input.{{ p.entity_field | pascal_case }} ?? DBNull.Value{% elif p.expression is defined %}{{ p.expression }}{% elif p.value is defined %}"{{ p.value }}"{% else %}DBNull.Value /* TODO: bind {{ p.name }} */{% endif %} },
|
|
50
|
+
{% endfor %}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
var request = new {{ db_settings.request_type | default('ExternalizationRequest') }}
|
|
54
|
+
{
|
|
55
|
+
Operation = "{{ m.facade_operation }}",
|
|
56
|
+
Target = "{{ m.target }}",
|
|
57
|
+
DBType = {{ db_settings.dbtype_enum | default('DatabaseType') }}.{{ m.db_type_enum }},
|
|
58
|
+
{% if adapter.db_provider_enum %}
|
|
59
|
+
DBProvider = {{ db_settings.dbprovider_enum | default('DatabaseProvider') }}.{{ adapter.db_provider_enum }},
|
|
60
|
+
{% endif %}
|
|
61
|
+
Context = new Dictionary<string, string>
|
|
62
|
+
{
|
|
63
|
+
{ "SchemaName", configuration["{{ db_settings.schema_config_key }}"] ?? string.Empty },
|
|
64
|
+
},
|
|
65
|
+
InputParameters = inputParameters,
|
|
66
|
+
{% if adapter.extended_context_type and (out_params or cursor_params) %}
|
|
67
|
+
ExtendedContext = new {{ adapter.extended_context_type }}
|
|
68
|
+
{
|
|
69
|
+
{% if out_params and adapter.param_type_enum and adapter.output_params_field %}
|
|
70
|
+
{{ adapter.output_params_field }} = new Dictionary<string, {{ adapter.param_type_enum }}>
|
|
71
|
+
{
|
|
72
|
+
{% for p in out_params %}
|
|
73
|
+
{ "{{ p.name }}", {{ adapter.param_type_enum }}.{{ p.type | default(adapter.default_param_type) }} },
|
|
74
|
+
{% endfor %}
|
|
75
|
+
},
|
|
76
|
+
{% if sized and adapter.output_sizes_field %}
|
|
77
|
+
{{ adapter.output_sizes_field }} = new Dictionary<string, int>
|
|
78
|
+
{
|
|
79
|
+
{% for p in sized %}
|
|
80
|
+
{ "{{ p.name }}", {{ p.size }} },
|
|
81
|
+
{% endfor %}
|
|
82
|
+
},
|
|
83
|
+
{% endif %}
|
|
84
|
+
{% endif %}
|
|
85
|
+
{% if cursor_params and adapter.supports_cursors and adapter.cursor_field %}
|
|
86
|
+
{{ adapter.cursor_field }} = new[] { {% for p in cursor_params %}"{{ p.cursor_name | default(p.name) }}"{% if not loop.last %}, {% endif %}{% endfor %} },
|
|
87
|
+
{% endif %}
|
|
88
|
+
},
|
|
89
|
+
{% endif %}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
var response = _dbFacade.ExecuteAsync(request).GetAwaiter().GetResult();
|
|
93
|
+
|
|
94
|
+
if (response is null || !response.IsSuccess)
|
|
95
|
+
throw new Exception($"{{ m.target }} failed: {response?.Error?.ErrorMessage}");
|
|
96
|
+
|
|
97
|
+
// First cut: return the facade response verbatim. Map to a typed
|
|
98
|
+
// model here later if/when {{ m.returns }} mapping is required.
|
|
99
|
+
return response;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
{% else %}
|
|
103
|
+
{# ------------------------- non-relational / query ------------------------ #}
|
|
104
|
+
{% set ret = m.return_type_cs %}
|
|
105
|
+
public override {{ ret }} {{ m.name | pascal_case }}({% if m.entity is defined and m.entity %}{{ m.entity }} input, {% endif %}IConfiguration configuration)
|
|
106
|
+
{
|
|
107
|
+
var request = new {{ db_settings.request_type | default('ExternalizationRequest') }}
|
|
108
|
+
{
|
|
109
|
+
Operation = "{{ m.facade_operation }}",
|
|
110
|
+
Target = "{{ m.target }}",
|
|
111
|
+
DBType = {{ db_settings.dbtype_enum | default('DatabaseType') }}.{{ m.db_type_enum }},
|
|
112
|
+
{% if adapter.db_provider_enum %}
|
|
113
|
+
DBProvider = {{ db_settings.dbprovider_enum | default('DatabaseProvider') }}.{{ adapter.db_provider_enum }},
|
|
114
|
+
{% endif %}
|
|
115
|
+
InputParameters = new Dictionary<string, object>
|
|
116
|
+
{
|
|
117
|
+
{% if m.table is defined and m.table %}
|
|
118
|
+
{ "TableName", "{{ m.table }}" },
|
|
119
|
+
{% endif %}
|
|
120
|
+
{% for inp in m.inputs %}
|
|
121
|
+
{ "{{ inp.key }}", {% if inp.entity_field is defined %}input.{{ inp.entity_field | pascal_case }}{% elif inp.serialize_entity_field is defined %}JsonConvert.SerializeObject(input.{{ inp.serialize_entity_field | pascal_case }}){% elif inp.expression is defined %}{{ inp.expression }}{% elif inp.value is defined %}"{{ inp.value }}"{% else %}null /* TODO: bind {{ inp.key }} */{% endif %} },
|
|
122
|
+
{% endfor %}
|
|
123
|
+
},
|
|
124
|
+
{% if m.extended_context_action %}
|
|
125
|
+
ExtendedContext = new {{ m.extended_context_type | default('CassandraExtendedContext') }} { Action = "{{ m.extended_context_action }}" },
|
|
126
|
+
{% endif %}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
var response = _dbFacade.ExecuteAsync(request).GetAwaiter().GetResult();
|
|
130
|
+
|
|
131
|
+
// TODO: map `response` to {{ ret }} and return.
|
|
132
|
+
throw new NotImplementedException();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
{% endif %}
|
|
136
|
+
{% endfor %}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
{% else %}
|
|
140
|
+
// Generated by ND-SDK CLI as a STUB. Implement your provider logic here.
|
|
141
|
+
using Microsoft.Extensions.Configuration;
|
|
142
|
+
namespace {{ ns.provider }}
|
|
143
|
+
{
|
|
144
|
+
public class {{ provider.name }} : {{ provider.base | default('ProviderBase') }}
|
|
145
|
+
{
|
|
146
|
+
public {{ provider.name }}(IConfiguration configuration) : base(configuration) { }
|
|
147
|
+
|
|
148
|
+
// TODO: add provider methods.
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
{% endif %}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// AUTO-GENERATED BY ND-SDK CLI — DO NOT EDIT.
|
|
2
|
+
using Microsoft.Extensions.Configuration;
|
|
3
|
+
namespace {{ ns.provider }}
|
|
4
|
+
{
|
|
5
|
+
public abstract class ProviderBase
|
|
6
|
+
{
|
|
7
|
+
protected readonly IConfiguration Configuration;
|
|
8
|
+
protected ProviderBase(IConfiguration configuration) => Configuration = configuration;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// -----------------------------------------------------------------------------
|
|
2
|
+
// Generated by ND-SDK CLI as a STUB. This file is yours — implement here.
|
|
3
|
+
// It is written once and NOT overwritten on regenerate.
|
|
4
|
+
// -----------------------------------------------------------------------------
|
|
5
|
+
using Microsoft.Extensions.Configuration;
|
|
6
|
+
using {{ ns.service }};
|
|
7
|
+
{% if dtos %}
|
|
8
|
+
using {{ ns.dtos }};
|
|
9
|
+
{% endif %}
|
|
10
|
+
{% if models %}
|
|
11
|
+
using {{ ns.models }};
|
|
12
|
+
{% endif %}
|
|
13
|
+
{% if providers %}
|
|
14
|
+
using {{ ns.provider }};
|
|
15
|
+
{% endif %}
|
|
16
|
+
|
|
17
|
+
namespace {{ ns.service_impl }}
|
|
18
|
+
{
|
|
19
|
+
public class {{ service_name }}Service : I{{ service_name }}Service
|
|
20
|
+
{
|
|
21
|
+
{% if providers %}
|
|
22
|
+
{% for p in providers %}
|
|
23
|
+
private readonly {{ p.name }} _{{ p.name | camel_case }};
|
|
24
|
+
{% endfor %}
|
|
25
|
+
|
|
26
|
+
public {{ service_name }}Service({% for p in providers %}{{ p.name }} {{ p.name | camel_case }}{% if not loop.last %}, {% endif %}{% endfor %})
|
|
27
|
+
{
|
|
28
|
+
{% for p in providers %}
|
|
29
|
+
_{{ p.name | camel_case }} = {{ p.name | camel_case }};
|
|
30
|
+
{% endfor %}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
{% else %}
|
|
34
|
+
public {{ service_name }}Service() { }
|
|
35
|
+
|
|
36
|
+
{% endif %}
|
|
37
|
+
{% for ep in business_endpoints %}
|
|
38
|
+
{% set method = ep.service_method | default(ep.name | pascal_case) %}
|
|
39
|
+
{% set request_type = ep.request_dto | default(ep.request_model | default('')) %}
|
|
40
|
+
{% set response_type = ep.response_dto | default(ep.response_model | default('object')) %}
|
|
41
|
+
public {{ response_type }} {{ method }}({% if request_type %}{{ request_type }} input, {% endif %}IConfiguration configuration)
|
|
42
|
+
{
|
|
43
|
+
// TODO: map {{ request_type | default('request') }} to provider entity/entities, call providers, and return {{ response_type }}.
|
|
44
|
+
throw new NotImplementedException();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
{% endfor %}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// -----------------------------------------------------------------------------
|
|
2
|
+
// AUTO-GENERATED BY ND-SDK CLI — DO NOT EDIT.
|
|
3
|
+
// -----------------------------------------------------------------------------
|
|
4
|
+
using Microsoft.Extensions.DependencyInjection;
|
|
5
|
+
|
|
6
|
+
namespace {{ ns.service }}
|
|
7
|
+
{
|
|
8
|
+
public interface IService { }
|
|
9
|
+
|
|
10
|
+
public sealed class ServiceManager
|
|
11
|
+
{
|
|
12
|
+
private static IServiceProvider _serviceProvider;
|
|
13
|
+
|
|
14
|
+
public static void SetServiceProvider(IServiceProvider serviceProvider)
|
|
15
|
+
{
|
|
16
|
+
_serviceProvider = serviceProvider;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public static T GetService<T>() where T : IService
|
|
20
|
+
{
|
|
21
|
+
if (_serviceProvider == null)
|
|
22
|
+
throw new InvalidOperationException("ServiceProvider not set.");
|
|
23
|
+
|
|
24
|
+
using var scope = _serviceProvider.CreateScope();
|
|
25
|
+
return scope.ServiceProvider.GetRequiredService<T>();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
2
|
+
# Visual Studio Version 17
|
|
3
|
+
VisualStudioVersion = 17.0.31903.59
|
|
4
|
+
MinimumVisualStudioVersion = 10.0.40219.1
|
|
5
|
+
{% for proj in projects %}
|
|
6
|
+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "{{ proj.name }}", "{{ proj.path }}", "{{ '{' }}{{ proj.guid }}{{ '}' }}"
|
|
7
|
+
EndProject
|
|
8
|
+
{% endfor %}
|
|
9
|
+
Global
|
|
10
|
+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
11
|
+
Debug|Any CPU = Debug|Any CPU
|
|
12
|
+
Release|Any CPU = Release|Any CPU
|
|
13
|
+
EndGlobalSection
|
|
14
|
+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
15
|
+
{% for proj in projects %}
|
|
16
|
+
{{ '{' }}{{ proj.guid }}{{ '}' }}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
17
|
+
{{ '{' }}{{ proj.guid }}{{ '}' }}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
18
|
+
{{ '{' }}{{ proj.guid }}{{ '}' }}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
19
|
+
{{ '{' }}{{ proj.guid }}{{ '}' }}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
20
|
+
{% endfor %}
|
|
21
|
+
EndGlobalSection
|
|
22
|
+
EndGlobal
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{% if nuget_refs %}
|
|
2
|
+
<ItemGroup>
|
|
3
|
+
{% for ref in nuget_refs %}
|
|
4
|
+
<PackageReference Include="{{ ref.name }}"{% if ref.version %} Version="{{ ref.version }}"{% endif %} />
|
|
5
|
+
{% endfor %}
|
|
6
|
+
</ItemGroup>
|
|
7
|
+
{% endif %}
|
|
8
|
+
{% if project_references %}
|
|
9
|
+
<ItemGroup>
|
|
10
|
+
{% for ref in project_references %}
|
|
11
|
+
<ProjectReference Include="{{ ref.path }}" />
|
|
12
|
+
{% endfor %}
|
|
13
|
+
</ItemGroup>
|
|
14
|
+
{% endif %}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/launchsettings.json",
|
|
3
|
+
"profiles": {
|
|
4
|
+
"{{ service_name }}": {
|
|
5
|
+
"commandName": "Project",
|
|
6
|
+
"dotnetRunMessages": true,
|
|
7
|
+
"launchBrowser": true,
|
|
8
|
+
"launchUrl": "swagger",
|
|
9
|
+
"applicationUrl": "http://localhost:{{ svc.port | default(5000) }}",
|
|
10
|
+
"environmentVariables": {
|
|
11
|
+
{% for key, value in launch_env_vars.items() %}
|
|
12
|
+
"{{ key }}": "{{ value | replace('\\', '\\\\') | replace('"', '\\"') }}"{{ "," if not loop.last else "" }}
|
|
13
|
+
{% endfor %}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<Project Sdk="Microsoft.NET.Sdk.Web">
|
|
2
|
+
|
|
3
|
+
<PropertyGroup>
|
|
4
|
+
<TargetFramework>{{ dotnet }}</TargetFramework>
|
|
5
|
+
<Nullable>enable</Nullable>
|
|
6
|
+
<ImplicitUsings>enable</ImplicitUsings>
|
|
7
|
+
<RootNamespace>{{ project_namespace }}</RootNamespace>
|
|
8
|
+
<AssemblyName>{{ service_name }}</AssemblyName>
|
|
9
|
+
</PropertyGroup>
|
|
10
|
+
|
|
11
|
+
{% include "_csproj_refs.inc.j2" %}
|
|
12
|
+
</Project>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
|
2
|
+
|
|
3
|
+
<PropertyGroup>
|
|
4
|
+
<TargetFramework>{{ dotnet }}</TargetFramework>
|
|
5
|
+
<Nullable>enable</Nullable>
|
|
6
|
+
<ImplicitUsings>enable</ImplicitUsings>
|
|
7
|
+
<RootNamespace>{{ project_namespace }}</RootNamespace>
|
|
8
|
+
</PropertyGroup>
|
|
9
|
+
|
|
10
|
+
{% include "_csproj_refs.inc.j2" %}
|
|
11
|
+
</Project>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
using {{ ns.service }};
|
|
2
|
+
using {{ ns.service_impl }};
|
|
3
|
+
{% if providers %}
|
|
4
|
+
using {{ ns.provider }};
|
|
5
|
+
{% endif %}
|
|
6
|
+
|
|
7
|
+
var builder = WebApplication.CreateBuilder(args);
|
|
8
|
+
|
|
9
|
+
builder.Services.AddControllers();
|
|
10
|
+
builder.Services.AddEndpointsApiExplorer();
|
|
11
|
+
builder.Services.AddSwaggerGen(options => { options.EnableAnnotations(); });
|
|
12
|
+
|
|
13
|
+
builder.Services.AddKeyedSingleton("ServiceName", builder.Configuration["ServiceName"] ?? "{{ service_name }}");
|
|
14
|
+
|
|
15
|
+
// Clean architecture: constructor injection, no static service locator.
|
|
16
|
+
builder.Services.AddScoped<I{{ service_name }}Service, {{ service_name }}Service>();
|
|
17
|
+
{% for p in providers %}
|
|
18
|
+
builder.Services.AddScoped<{{ p.name }}>();
|
|
19
|
+
{% endfor %}
|
|
20
|
+
|
|
21
|
+
{% for fragment in package_registrations %}
|
|
22
|
+
{{ fragment }}
|
|
23
|
+
|
|
24
|
+
{% endfor %}
|
|
25
|
+
var app = builder.Build();
|
|
26
|
+
|
|
27
|
+
if (app.Environment.IsDevelopment())
|
|
28
|
+
{
|
|
29
|
+
app.UseSwagger();
|
|
30
|
+
app.UseSwaggerUI();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
app.UseAuthorization();
|
|
34
|
+
app.MapControllers();
|
|
35
|
+
app.Run();
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
type: microservice
|
|
2
|
+
style: clean
|
|
3
|
+
description: Clean architecture — Domain / Application / Infrastructure / Api projects.
|
|
4
|
+
controller_style: constructor
|
|
5
|
+
namespaces:
|
|
6
|
+
models: "{ns}.Domain.Entities"
|
|
7
|
+
dtos: "{ns}.Application.DTOs"
|
|
8
|
+
entities: "{ns}.Domain.Entities"
|
|
9
|
+
bo: "{ns}.Domain.BO"
|
|
10
|
+
service: "{ns}.Application.Interfaces"
|
|
11
|
+
service_impl: "{ns}.Application.Services"
|
|
12
|
+
provider: "{ns}.Infrastructure.Providers"
|
|
13
|
+
controller: "{ns}.Api.Controllers"
|
|
14
|
+
solution:
|
|
15
|
+
template: Solution.sln.j2
|
|
16
|
+
projects:
|
|
17
|
+
- id: domain
|
|
18
|
+
dir: "{service}/{service}.Domain"
|
|
19
|
+
namespace: "{ns}.Domain"
|
|
20
|
+
csproj: { template: ClassLib.csproj.j2, path: "{service}.Domain.csproj" }
|
|
21
|
+
artifacts:
|
|
22
|
+
- { template: Model.cs.j2, path: "Entities/{model}.cs", layer: model, scope: per_model }
|
|
23
|
+
- { template: Entity.cs.j2, path: "Entities/{entity}.cs", layer: entity, scope: per_entity }
|
|
24
|
+
- { template: BO.cs.j2, path: "BO/{bo}.cs", layer: bo, scope: per_bo, owner: user }
|
|
25
|
+
|
|
26
|
+
- id: application
|
|
27
|
+
dir: "{service}/{service}.Application"
|
|
28
|
+
namespace: "{ns}.Application"
|
|
29
|
+
references: [domain]
|
|
30
|
+
nuget:
|
|
31
|
+
- { name: Microsoft.Extensions.Configuration.Abstractions, version: 8.0.0 }
|
|
32
|
+
csproj: { template: ClassLib.csproj.j2, path: "{service}.Application.csproj" }
|
|
33
|
+
artifacts:
|
|
34
|
+
- { template: Dto.cs.j2, path: "DTOs/{dto}.cs", layer: dto, scope: per_dto }
|
|
35
|
+
- { template: IService.cs.j2, path: "Interfaces/I{service}Service.cs", layer: iservice }
|
|
36
|
+
- { template: Service.cs.j2, path: "Services/{service}Service.cs", layer: service, owner: user }
|
|
37
|
+
|
|
38
|
+
- id: infrastructure
|
|
39
|
+
dir: "{service}/{service}.Infrastructure"
|
|
40
|
+
namespace: "{ns}.Infrastructure"
|
|
41
|
+
references: [application, domain]
|
|
42
|
+
nuget:
|
|
43
|
+
- { name: Microsoft.Extensions.Configuration.Abstractions, version: 8.0.0 }
|
|
44
|
+
csproj: { template: ClassLib.csproj.j2, path: "{service}.Infrastructure.csproj" }
|
|
45
|
+
artifacts:
|
|
46
|
+
- { template: ProviderBase.cs.j2, path: "Providers/ProviderBase.cs", layer: provider-base }
|
|
47
|
+
- { template: DbProviderBase.cs.j2, path: "Providers/{provider}Base.cs", layer: provider-base, scope: per_provider, only: db_provider }
|
|
48
|
+
- { template: Provider.cs.j2, path: "Providers/{provider}.cs", layer: provider, scope: per_provider, owner: user }
|
|
49
|
+
|
|
50
|
+
- id: api
|
|
51
|
+
host: true
|
|
52
|
+
dir: "{service}/{service}.Api"
|
|
53
|
+
namespace: "{ns}.Api"
|
|
54
|
+
references: [application, infrastructure]
|
|
55
|
+
nuget:
|
|
56
|
+
- { name: Swashbuckle.AspNetCore, version: 6.5.0 }
|
|
57
|
+
- { name: Swashbuckle.AspNetCore.Annotations, version: 6.5.0 }
|
|
58
|
+
csproj: { template: Api.csproj.j2, path: "{service}.Api.csproj" }
|
|
59
|
+
artifacts:
|
|
60
|
+
- { hook: program, path: "Program.cs", layer: program }
|
|
61
|
+
- { hook: appsettings, path: "appsettings.json", layer: appsettings }
|
|
62
|
+
- { template: Dockerfile.j2, path: "Dockerfile", layer: docker }
|
|
63
|
+
- { template: launchSettings.json.j2, path: "Properties/launchSettings.json", layer: launch }
|
|
64
|
+
- { template: Controller.cs.j2, path: "Controllers/{service}Controller.cs", layer: controller, locked: true }
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
using {{ ns.service }};
|
|
2
|
+
{% if providers %}
|
|
3
|
+
using {{ ns.provider }};
|
|
4
|
+
{% endif %}
|
|
5
|
+
{% if obs_enabled %}
|
|
6
|
+
using ND.Observability.Framework.Core.Application.Handlers.Interface.Logging;
|
|
7
|
+
using ND.Observability.Framework.Core.Application.Services;
|
|
8
|
+
{% endif %}
|
|
9
|
+
{% for pkg, _s in resolved_packages %}
|
|
10
|
+
{% if pkg.key == 'db_provider' %}
|
|
11
|
+
using DataAccessLayer.Facade;
|
|
12
|
+
using DataAccessLayer.Infrastructure;
|
|
13
|
+
using DB_Provider.Extensions;
|
|
14
|
+
using N_DB_Provider.Core.Application.Handler.Interface;
|
|
15
|
+
using N_DB_Provider.Core.Application.Services;
|
|
16
|
+
{% endif %}
|
|
17
|
+
{% if pkg.key == 'client_provider' %}
|
|
18
|
+
using Client_Provider.Infrastructure;
|
|
19
|
+
{% endif %}
|
|
20
|
+
{% if pkg.key == 'exception_handling' %}
|
|
21
|
+
using ND.ExceptionFramework.Extentions;
|
|
22
|
+
using ND.ExceptionFramework.PlatformAdapters.WebApi.Middleware;
|
|
23
|
+
{% endif %}
|
|
24
|
+
{% if pkg.key == 'file_storage_azure' %}
|
|
25
|
+
using ND.FW.FileStorageProvider.Azure.Extensions;
|
|
26
|
+
{% endif %}
|
|
27
|
+
{% endfor %}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
var builder = WebApplication.CreateBuilder(args);
|
|
31
|
+
|
|
32
|
+
builder.Services.AddControllers();
|
|
33
|
+
builder.Services.AddEndpointsApiExplorer();
|
|
34
|
+
builder.Services.AddSwaggerGen(options => { options.EnableAnnotations(); });
|
|
35
|
+
|
|
36
|
+
builder.Services.AddKeyedSingleton("ServiceName", builder.Configuration["ServiceName"] ?? "{{ service_name }}");
|
|
37
|
+
builder.Services.AddScoped<I{{ service_name }}Service, {{ service_name }}Service>();
|
|
38
|
+
{% for p in providers %}
|
|
39
|
+
builder.Services.AddScoped<{{ p.name }}>();
|
|
40
|
+
{% endfor %}
|
|
41
|
+
|
|
42
|
+
{% for fragment in package_registrations %}
|
|
43
|
+
{{ fragment }}
|
|
44
|
+
|
|
45
|
+
{% endfor %}
|
|
46
|
+
var app = builder.Build();
|
|
47
|
+
ServiceManager.SetServiceProvider(app.Services);
|
|
48
|
+
|
|
49
|
+
{% for fragment in app_registrations | default([]) %}
|
|
50
|
+
{{ fragment }}
|
|
51
|
+
|
|
52
|
+
{% endfor %}
|
|
53
|
+
if (app.Environment.IsDevelopment())
|
|
54
|
+
{
|
|
55
|
+
app.UseSwagger();
|
|
56
|
+
app.UseSwaggerUI();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
app.UseAuthorization();
|
|
60
|
+
app.MapControllers();
|
|
61
|
+
app.Run();
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<Project Sdk="Microsoft.NET.Sdk.Web">
|
|
2
|
+
|
|
3
|
+
<PropertyGroup>
|
|
4
|
+
<TargetFramework>{{ dotnet }}</TargetFramework>
|
|
5
|
+
<Nullable>enable</Nullable>
|
|
6
|
+
<ImplicitUsings>enable</ImplicitUsings>
|
|
7
|
+
<RootNamespace>{{ project_namespace }}</RootNamespace>
|
|
8
|
+
<AssemblyName>{{ service_name }}</AssemblyName>
|
|
9
|
+
</PropertyGroup>
|
|
10
|
+
|
|
11
|
+
{% include "_csproj_refs.inc.j2" %}
|
|
12
|
+
</Project>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
type: microservice
|
|
2
|
+
style: layered
|
|
3
|
+
description: Single project, layered (Controllers / Service / Provider / Entities / BO / Models).
|
|
4
|
+
controller_style: service_manager
|
|
5
|
+
namespaces:
|
|
6
|
+
models: "{ns}.Models"
|
|
7
|
+
dtos: "{ns}.Dtos"
|
|
8
|
+
entities: "{ns}.Entities"
|
|
9
|
+
bo: "{ns}.BO"
|
|
10
|
+
service: "{ns}.Service"
|
|
11
|
+
service_impl: "{ns}.Service"
|
|
12
|
+
provider: "{ns}.Provider"
|
|
13
|
+
controller: "{ns}.Controllers"
|
|
14
|
+
solution:
|
|
15
|
+
template: Solution.sln.j2
|
|
16
|
+
projects:
|
|
17
|
+
- id: app
|
|
18
|
+
host: true
|
|
19
|
+
dir: "{service}"
|
|
20
|
+
namespace: "{ns}"
|
|
21
|
+
nuget:
|
|
22
|
+
- { name: Swashbuckle.AspNetCore, version: 6.5.0 }
|
|
23
|
+
- { name: Swashbuckle.AspNetCore.Annotations, version: 6.5.0 }
|
|
24
|
+
csproj: { template: Project.csproj.j2, path: "{service}.csproj" }
|
|
25
|
+
references: []
|
|
26
|
+
artifacts:
|
|
27
|
+
- { hook: program, path: "Program.cs", layer: program }
|
|
28
|
+
- { hook: appsettings, path: "appsettings.json", layer: appsettings }
|
|
29
|
+
- { template: Dockerfile.j2, path: "Dockerfile", layer: docker }
|
|
30
|
+
- { hook: launch, path: "Properties/launchSettings.json", layer: launch }
|
|
31
|
+
- { template: ServiceManager.cs.j2, path: "Service/ServiceManager.cs", layer: service-manager }
|
|
32
|
+
- { template: Controller.cs.j2, path: "Controllers/{service}Controller.cs", layer: controller, locked: true }
|
|
33
|
+
- { template: IService.cs.j2, path: "Service/I{service}Service.cs", layer: iservice }
|
|
34
|
+
- { template: Service.cs.j2, path: "Service/{service}Service.cs", layer: service, owner: user }
|
|
35
|
+
- { template: Dto.cs.j2, path: "Dtos/{dto}.cs", layer: dto, scope: per_dto }
|
|
36
|
+
- { template: Entity.cs.j2, path: "Entities/{entity}.cs", layer: entity, scope: per_entity }
|
|
37
|
+
- { template: Model.cs.j2, path: "Models/{model}.cs", layer: model, scope: per_model }
|
|
38
|
+
- { template: BO.cs.j2, path: "BO/{bo}.cs", layer: bo, scope: per_bo, owner: user }
|
|
39
|
+
- { template: ProviderBase.cs.j2, path: "Provider/ProviderBase.cs", layer: provider-base }
|
|
40
|
+
- { template: DbProviderBase.cs.j2, path: "Provider/{provider}Base.cs", layer: provider-base, scope: per_provider, only: db_provider }
|
|
41
|
+
- { template: Provider.cs.j2, path: "Provider/{provider}.cs", layer: provider, scope: per_provider }
|