Настоящият документ описва примерни стъпки за разработка на адаптер за RegiX.
- 1. Създаване на проект
- 2. Добавяне на зависимости чрез инсталация на Nuget пакети
- 4. Добавяне на схеми, метаданни, трансформации
В настоящата инструкция, за разработка на адаптерите се използва .NET Framework. Създайте три проекта със следните типове и примерни имена:
- RegiX.NameAdapter с тип Class Library (.NET Standard)
- RegiX.NameAdapter.Mock с тип Class Library (.NET Standard)
- RegiX.NameAdapter.Test с тип MSTest Test Project (.NET Core)
След създаване на проектите, премахнете автоматично създадените класове за всеки от създадените проекти.
Променете DefaultNamespace, така че да съдържа името на компанията разработчик:
- Company.RegiX.NameAdapter
- Company.RegiX.NameAdapter.Mock
- Company.RegiX.NameAdapter.Test
Структурата на Namespace е: Company.RegiX.NameAdapter
Редактирайте описанието на проекта (auhtor, company, description) като натиснете десен бутон на мишката върху името на проекта, изберете Properties и то менюто в ляво Package.
За всеки от проектите, натиснете върху наименованието му. Между таговете </PropertyGroup> и </Project>
добавете:
- За адаптер Company.RegiX.NameAdapter
<ItemGroup>
<Content Include="XMLSamples\*\*.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="XMLSchemas\*\Transformations\*.xslt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="XMLSchemas\*\*.xsd">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="XMLMetaData\*\*.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
- За адаптер Company.RegiX.NameAdapter.Mock кода се добавя между
</PropertyGroup> и </Project>
.
<ItemGroup>
<Content Include="XMLData\*\*.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
За работа по създадените проекти с Nuget Packet Manager, необходимо е да генерирате XML метаописания. В директориите на проектите RegiX.NameAdapter и RegiX.NameAdapter.Mock изпълнете командата nuget spec
, за да създадете .nuspec файлове. Последна версия на nuget.exe ще откриете на адрес: https://www.nuget.org/downloads.
Редактирайте съдържанието на .nuspec файловете RegiX.**Name**Adapter.nuspec
и RegiX.**Name**Adapter.Mock
, като изтриете елементите <licenceURL>, <projectURL>, <iconURL>,<copyright2020>, <tags>
.
В директорията на проект RegiX.NameAdapter, създайте следните поддиректории:
- AdapterService
- APIService
- XMLMetaData\RegiX.NameAdapter
- XMLSamples\RegiX.NameAdapter
- XMLSchemas\RegiX.NameAdapter
Добавете път към адрес на местоположение на Nuget пакети, като изберете Tools, Nuget Package Manager, Packet Manager Settings. От менюто в ляво се избира: Pacakage Sources. Добавянето на пътя към Nuget пакетите става чрез натискането на бутона плюс и след това попълването на Името и в полето Source се посочва пътя към пакетите.
След задаване на адрес на хранилище с Nuget пакети, е необходимо те да бъдат инсталирани. За проектите добавете следните референции, като натиснете десен бутон върху името на проекта и изберете Manage NuGet Packages от контекстното меню:
- RegiX.Adapters.Common в проект RegiX.NameAdapter
- RegiX.Adapters.Mocks в проект RegiX.NameAdapter.Mock
- RegiX.Adapters.TestUtils в проект RegiX.NameAdapter.Test
Създайте спрямо описанието в стандарта за раработка на адаптери следние файлове, които да служат като класове, в съответните директории.
RegiX.**Name**Adapter\RegiX.**Name**Adapter\AdapterService\I**Name**Adapter.cs
RegiX.**Name**Adapter\RegiX.**Name**Adapter\AdapterService\NameAdapter.cs
RegiX.**Name**Adapter\RegiX.**Name**Adapter\APIService\I**Name**API.cs
RegiX.**Name**Adapter\RegiX.**Name**Adapter\APIService\**Name**API.cs
Във всеки от създадените в т. 3 класове е необходимо да въведете метод за всяка операция. Кодът използван по-долу е примерен. Необходимо е да промените namespace
според наименованието на вашите организация и име на проект.
- В INameAdapter.cs използвайте:
using System.ComponentModel;
using System.ServiceModel;
using TechnoLogica.RegiX.Common;
using TechnoLogica.RegiX.Common.DataContracts;
using TechnoLogica.RegiX.Common.ObjectMapping;
namespace DAEU.RegiX.SampleAdapter.AdapterService
{
[ServiceContract]
[Description("Примерен адаптер")]
public interface ISampleAdapter : IAdapterServiceWCF
{
[OperationContract]
[Description("Примерна услуга 1")]
CommonSignedResponse<ExampleRequest, ExampleResponse> Example(ExampleRequest argument, AccessMatrix accessMatrix, AdapterAdditionalParameters aditionalParameters);
[OperationContract]
[Description("Примерна услуга 2")]
CommonSignedResponse<ExampleRequest, ExampleResponse> Example2(ExampleRequest argument, AccessMatrix accessMatrix, AdapterAdditionalParameters aditionalParameters);
[OperationContract]
[Description("Примерна услуга 3")]
CommonSignedResponse<ExampleRequest, ExampleResponse> Example3(ExampleRequest argument, AccessMatrix accessMatrix, AdapterAdditionalParameters aditionalParameters);
}
}
- В NameAdapter.cs използвайте:
using System.ComponentModel.Composition;
using TechnoLogica.RegiX.Adapters.Common;
using TechnoLogica.RegiX.Adapters.Common.DataContracts;
using TechnoLogica.RegiX.Adapters.Common.ExportExtension;
using TechnoLogica.RegiX.Adapters.Common.ObjectMapping;
using TechnoLogica.RegiX.Common;
using TechnoLogica.RegiX.Common.DataContracts;
using TechnoLogica.RegiX.Common.DataContracts.Parameter;
using TechnoLogica.RegiX.Common.ObjectMapping;
using TechnoLogica.RegiX.Common.Utils;
namespace DAEU.RegiX.SampleAdapter.AdapterService
{
[Export(typeof(IAdapterService))]
[ExportFullName(typeof(SampleAdapter), typeof(IAdapterService))]
[ExportSimpleName(typeof(SampleAdapter), typeof(IAdapterService))]
public class SampleAdapter : BaseAdapterService, ISampleAdapter
{
public CommonSignedResponse<ExampleRequest, ExampleResponse> Example(ExampleRequest argument, AccessMatrix accessMatrix, AdapterAdditionalParameters aditionalParameters)
{
ExampleResponse response = new ExampleResponse();
response.StringData = argument.Identifier;
response.StringData2 = "Operation 1";
var mapper = new SelfMapper<ExampleResponse>(accessMatrix);
ExampleResponse result = new ExampleResponse();
mapper.Map(response, result);
return SigningUtils.CreateAndSign(argument, result, accessMatrix, aditionalParameters);
}
public CommonSignedResponse<ExampleRequest, ExampleResponse> Example2(ExampleRequest argument, AccessMatrix accessMatrix, AdapterAdditionalParameters aditionalParameters)
{
ExampleResponse response = new ExampleResponse();
response.StringData = argument.Identifier;
response.StringData2 = "Operation 2";
var mapper = new SelfMapper<ExampleResponse>(accessMatrix);
ExampleResponse result = new ExampleResponse();
mapper.Map(response, result);
return SigningUtils.CreateAndSign(argument, result, accessMatrix, aditionalParameters);
}
public CommonSignedResponse<ExampleRequest, ExampleResponse> Example3(ExampleRequest argument, AccessMatrix accessMatrix, AdapterAdditionalParameters aditionalParameters)
{
ExampleResponse response = new ExampleResponse();
response.StringData = argument.Identifier;
response.StringData2 = "Operation 3";
var mapper = new SelfMapper<ExampleResponse>(accessMatrix);
ExampleResponse result = new ExampleResponse();
mapper.Map(response, result);
return SigningUtils.CreateAndSign(argument, result, accessMatrix, aditionalParameters);
}
}
}
- NameAPI.cs
using DAEU.RegiX.SampleAdapter.AdapterService;
using System.ComponentModel.Composition;
using TechnoLogica.RegiX.Adapters.Common;
using TechnoLogica.RegiX.Adapters.Common.ExportExtension;
using TechnoLogica.RegiX.Common;
using TechnoLogica.RegiX.Common.TransportObjects;
namespace DAEU.RegiX.SampleAdapter.APIService
{
[ExportFullName(typeof(ISampleAPI), typeof(IAPIService))]
[Export(typeof(IAPIService))]
public class SampleAPI : BaseAPIService, ISampleAPI
{
public ServiceResultDataSigned<ExampleRequest, ExampleResponse> Example(ServiceRequestData<ExampleRequest> argument)
{
return AdapterClient.Execute<ISampleAdapter, ExampleRequest, ExampleResponse>(
(i, r, a, o) => i.Example(r, a, o),
argument);
}
public ServiceResultDataSigned<ExampleRequest, ExampleResponse> Example2(ServiceRequestData<ExampleRequest> argument)
{
return AdapterClient.Execute<ISampleAdapter, ExampleRequest, ExampleResponse>(
(i, r, a, o) => i.Example2(r, a, o),
argument);
}
public ServiceResultDataSigned<ExampleRequest, ExampleResponse> Example3(ServiceRequestData<ExampleRequest> argument)
{
return AdapterClient.Execute<ISampleAdapter, ExampleRequest, ExampleResponse>(
(i, r, a, o) => i.Example3(r, a, o),
argument);
}
}
}
- INameAPI.cs
using System.ComponentModel;
using System.ServiceModel;
using TechnoLogica.RegiX.Adapters.Common.Attributes;
using TechnoLogica.RegiX.Common;
using TechnoLogica.RegiX.Common.TransportObjects;
namespace DAEU.RegiX.SampleAdapter.APIService
{
[ServiceContract]
[XmlSerializerFormat]
[Description("API на примерен адаптер")]
public interface ISampleAPI : IAPIService
{
[OperationContract]
[Description("Изпълнява примерна услуга 1")]
ServiceResultDataSigned<ExampleRequest, ExampleResponse> Example(ServiceRequestData<ExampleRequest> argument);
[OperationContract]
[Description("Изпълнява примерна услуга 2")]
[Info(requestXSD: "ExampleRequest.xsd", responseXSD: "ExampleResponse.xsd",
sampleRequest: "ExampleRequest.xml",
sampleResponse: "ExampleResponse.xml",
requestXSLT: "ExampleRequest.xslt",
responseXSLT: "ExampleResponse.xslt", metaDataXML: "Example.xml")]
ServiceResultDataSigned<ExampleRequest, ExampleResponse> Example2(ServiceRequestData<ExampleRequest> argument);
[OperationContract]
[Description("Изпълнява примерна услуга 3")]
[Info(requestXSD: "ExampleRequest.xsd", responseXSD: "ExampleResponse.xsd",
sampleRequest: "ExampleRequest.xml",
sampleResponse: "ExampleResponse.xml",
requestXSLT: "ExampleRequest.xslt",
responseXSLT: "ExampleResponse.xslt", metaDataXML: "Example.xml")]
ServiceResultDataSigned<ExampleRequest, ExampleResponse> Example3(ServiceRequestData<ExampleRequest> argument);
}
}
Класовете INameAPI.cs и NameAPI.cs работят на ядрото на RegiX. INameAdapter.cs и NameAdapter.cs работят при регистъра, за който разработваме адаптер.
Във всеки от класовете е необходимо да въведете метод за всяка операция. Можете да генерирате класове от xml схеми чрез инструмента Xml2Code или да използвате примерния код по-долу. Необходимо е да промените връзките и namespace
, според наименованието на вашите организация и име на проект и да добавите допълнителни операции.
RegiX.**Name**Adapter\RegiX.**Name**Adapter\XMLSchemas\RegiX.**Name**Adapter\ExampleRequest.xsd
RegiX.**Name**Adapter\RegiX.**Name**Adapter\XMLSchemas\RegiX.**Name**Adapter\ExampleResponse.xsd
RegiX.**Name**Adapter\RegiX.**Name**Adapter\XMLSchemas\RegiX.**Name**Adapter\ExampleRequest.designer.cs
RegiX.**Name**Adapter\RegiX.**Name**Adapter\XMLSchemas\RegiX.**Name**Adapter\ExampleResponse.designer.cs
RegiX.**Name**Adapter\RegiX.**Name**Adapter\XMLSchemas\RegiX.**Name**Adapter\Transformations\ExampleRequest.sps
RegiX.**Name**Adapter\RegiX.**Name**Adapter\XMLSchemas\RegiX.**Name**Adapter\Transformations\ExampleResponse.sps
RegiX.**Name**Adapter\RegiX.**Name**Adapter\XMLSchemas\RegiX.**Name**Adapter\Transformations\ExampleRequest.xslt
RegiX.**Name**Adapter\RegiX.**Name**Adapter\XMLSchemas\RegiX.**Name**Adapter\Transformations\ExampleResponse.xml
RegiX.**Name**Adapter\RegiX.**Name**Adapter\XMLSchemas\RegiX.**Name**Adapter\Transformations\ExampleResponse.xslt
RegiX.**Name**Adapter\RegiX.**Name**Adapter\XMLMetaData\RegiX.**Name**Adapter\Example.xml
RegiX.**Name**Adapter\RegiX.**Name**Adapter\XMLSamples\RegiX.**Name**Adapter\ExampleRequest.xml
RegiX.**Name**Adapter\RegiX.**Name**Adapter\XMLSamples\RegiX.**Name**Adapter\ExampleResponse.xml