{"id":16494286,"url":"https://github.com/sayedihashimi/dotnetcoreservicetemplate","last_synced_at":"2025-10-17T04:19:41.043Z","repository":{"id":143152341,"uuid":"91919379","full_name":"sayedihashimi/DotNetCoreServiceTemplate","owner":"sayedihashimi","description":null,"archived":false,"fork":false,"pushed_at":"2017-05-22T17:04:06.000Z","size":53,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-11T22:19:45.363Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sayedihashimi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-20T22:15:40.000Z","updated_at":"2018-06-25T10:11:17.000Z","dependencies_parsed_at":"2023-04-03T21:47:50.799Z","dependency_job_id":null,"html_url":"https://github.com/sayedihashimi/DotNetCoreServiceTemplate","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sayedihashimi%2FDotNetCoreServiceTemplate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sayedihashimi%2FDotNetCoreServiceTemplate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sayedihashimi%2FDotNetCoreServiceTemplate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sayedihashimi%2FDotNetCoreServiceTemplate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sayedihashimi","download_url":"https://codeload.github.com/sayedihashimi/DotNetCoreServiceTemplate/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241335596,"owners_count":19946086,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-11T14:12:58.775Z","updated_at":"2025-10-17T04:19:35.992Z","avatar_url":"https://github.com/sayedihashimi.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Lykke Template for Internal API\nThis template should be used for internal API development\n\n## Getting Started\n\n### Installation\nTo install this template run the following command\n\n```ps\ndotnet new -i Lykke.Template::*\n```\n\nIf the template is changed, you can run above command again to update local installation.\n\n### Usage\nTo create a new solution:\n\n* navigate to the folder where solution folder should be created\n\n* run the following command:\n    ```\n    dotnet new LykkeTemplate -n Lykke.Assets -s Assets\n    ```\n    `-n` is the parameter for the name of the new _folder_, _solution_ and the root _namespace_.\n\n    `-s` is the short name for some functions used in the generated code (ex: `serivces.AddAssetsRepository()`).\n\n    \u003e to list all available command parameters run:\n    \u003e ```\n    \u003e dotnet new LykkeTemplate -h\n    \u003e ```\n\nThis will create a folder with a solution named `Lykke.Assets` with 4 projects.\n\n## Project Structure\n\n### 1. Abstractions Project\nThis project should contain only functionality definition abstracted from implementation details.\nUsually contains `interface` files.\n\n\u003e example `ISamplesRepository`:\n\u003e ```cs\n\u003e namespace Lykke.Template.Abstractions\n\u003e {\n\u003e     public interface ISample\n\u003e     {\n\u003e         string Id { get; }\n\u003e         string Name { get; }\n\u003e         string Description { get; }\n\u003e     }\n\u003e \n\u003e     public class Sample : ISample\n\u003e     {\n\u003e         //interface properties and static mapping methods\n\u003e     }\n\u003e \n\u003e     public interface ISamplesRepository\n\u003e     {\n\u003e         Task InsertAsync(ISample model);\n\u003e         Task UpdateAsync(ISample model);\n\u003e         Task\u003cISample\u003e GetAsync(string id);\n\u003e         Task\u003cIEnumerable\u003cISample\u003e\u003e GetAsync();\n\u003e     }\n\u003e }\n\u003e ```\n\n### 2. Azure Project\nThis project should contain _Azure_ implementations for definitions from _Abstractions Project_.\n\n\u003e example `SamplesRepository`:\n\u003e ```cs\n\u003e namespace Lykke.Template.Azure\n\u003e {\n\u003e     public class SampleEntity : TableEntity, ISample\n\u003e     {\n\u003e         //interface properties and static mapping methods\n\u003e     }\n\u003e \n\u003e     public class SamplesRepository : ISamplesRepository\n\u003e     {\n\u003e         public Task InsertAsync(ISample model)\n\u003e         {\n\u003e             var entity = SampleEntity.Map(model);\n\u003e             return _tableStorage.InsertAsync(entity);\n\u003e         }\n\u003e \n\u003e         //implementations of other methods\n\u003e     }\n\u003e }\n\u003e ```\n\n**Project Dependencies**:\n* _Abstractions Project_\n\n**NuGet dependencies**:\n* _Lykke.AzureStorage_: for Azure storage data manupulations (persisting and retriving)\n\n### 3. WebApi Project\nThis project should contain controllers to expose functionality as a Rest service.\n\n\u003e example `SamplesController`:\n\u003e ```cs\n\u003e namespace Lykke.Template.WebApi.Controllers\n\u003e {\n\u003e     [Authorize]\n\u003e     [Route(\"api/[controller]\")]\n\u003e     public class SamplesController : Controller\n\u003e     {\n\u003e         [HttpPost]\n\u003e         public Task\u003cIActionResult\u003e InsertAsync([FromBody] Sample model)\n\u003e         {\n\u003e             return _samplesRepository\n\u003e                 .InsertAsync(model)\n\u003e                 .ToActionResult();\n\u003e         }\n\u003e         \n\u003e         //implementations of other methods\n\u003e     }\n\u003e }\n\n**Project Dependencies**:\n* _Abstractions Project_\n* _Azure Project_\n\n**NuGet dependencies**:\n* _Lykke.ApiAuth.Azure_: Api Authentication/Authorization implementation on Azure\n* _Lykke.ApiAuth.Mvc_: MVC Authentication MiddleWare and other extensions.\n* _Lykke.Extensions_: For reading settings from URL\n    \u003e Usage:\n    \u003e ```cs\n    \u003e var builder = new ConfigurationBuilder()\n    \u003e     .AddFromConfiguredUrl(\"TEMPLATE_API_SETTINGS_URL\");\n    \u003e Configuration = builder.Build();\n    \u003e\n    \u003e var apiAzureConfig = Configuration\n    \u003e     .GetSection(\"LykkeApiAuth\")\n    \u003e     .Get\u003cApiAuthAzureConfig\u003e();\n    \u003e ```\n    \u003e `TEMPLATE_API_SETTINGS_URL` sould be configured to the settings url.\n* _Lykke.Http_: Common classes to be serialized between `api` and `api client`\n\n### 4. WebClient Project\nThis project should contain proxy classes, implementing interfaces from _Abstractions Project_ by sending inputs to _WebApi_ rest service, and returning results.\n\n\u003e example `SamplesRepositoryClient`:\n\u003e ```cs\n\u003e namespace Lykke.Template.WebClient\n\u003e {\n\u003e     public class SamplesRepositoryClient : \u003e ISamplesRepository\n\u003e     {\n\u003e         private readonly RestClient _restClient;\n\u003e         private const string Endpoint = \"api/samples\";\n\u003e \n\u003e         public Task InsertAsync(ISample model)\n\u003e         {\n\u003e             return _restClient.PostAsync($\"{Endpoint}\", model);\n\u003e         }\n\u003e \n\u003e         //implementations of other methods\n\u003e     }\n\u003e }\n\u003e ```\n\n## Additional Notes\n### Exception ahndling:\nExceptions are being simplified and serialized and returned as rest result.\n\u003e 400 BadRequest\n\u003e \n\u003e ```json\n\u003e {\n\u003e   \"message\": \"Conflict\",\n\u003e   \"innerException\": null\n\u003e }\n\u003e ```\n\nWhen rest client gets `400 - BadRequest` result, it tries to deserialize it as an exception and if is succeeds throws new exception, so we can use `try / catch` on the client side, and will get the error thrown in API.\n\n\u003e For exapmle if we try to insert an item with an already existing Id, we will get Exception with \"Conflict\" message at client side.\n\u003e \n\u003e ```cs\n\u003e var services = new ServiceCollection()\n\u003e     .AddTemplateWebClient(/* */)\n\u003e     .BuildServiceProvider();\n\u003e \n\u003e var samplesService = services.GetService\u003cISamplesRepository\u003e();\n\u003e \n\u003e try\n\u003e {\n\u003e     await samplesService.InsertAsync(item);\n\u003e     Console.WriteLine(\"Added sample\");\n\u003e }\n\u003e catch (Exception e)\n\u003e {\n\u003e     Console.WriteLine(e);\n\u003e }\n\u003e ```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsayedihashimi%2Fdotnetcoreservicetemplate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsayedihashimi%2Fdotnetcoreservicetemplate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsayedihashimi%2Fdotnetcoreservicetemplate/lists"}