Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
azabluda committed May 30, 2018
2 parents 8a3f0dd + b291960 commit 5e8503a
Show file tree
Hide file tree
Showing 194 changed files with 11,898 additions and 3,107 deletions.
6 changes: 6 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Project>
<PropertyGroup>
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)StyleNoDoc.ruleset</CodeAnalysisRuleSet>
<LangVersion>latest</LangVersion>
</PropertyGroup>
</Project>
10 changes: 10 additions & 0 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project>
<ItemGroup>
<AdditionalFiles Include="$(MSBuildThisFileDirectory)stylecop.json">
<Link>stylecop.json</Link>
</AdditionalFiles>
<PackageReference Include="StyleCop.Analyzers" Version="1.1.0-beta007">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion GitVersion.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
next-version: 2.0.0-dev
next-version: 2.1.0-dev

branches:
develop:
Expand Down
39 changes: 31 additions & 8 deletions InfoCarrier.Core.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27004.2005
VisualStudioVersion = 15.0.27703.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InfoCarrier.Core", "src\InfoCarrier.Core\InfoCarrier.Core.csproj", "{6B24F793-C93B-4869-A99B-AC51EE2C82AF}"
EndProject
Expand All @@ -13,14 +13,20 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InfoCarrier.Core.Functional
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sample", "sample", "{4A57BB06-6B50-4CF8-A601-E5572247FB5F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WcfSample.Shared", "sample\WcfSample.Shared\WcfSample.Shared.csproj", "{4AF12B6E-9979-4146-86BC-F59F6D00E4A0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WcfSample.Server", "sample\WcfSample.Server\WcfSample.Server.csproj", "{C43F891C-7548-4E22-B0C6-A5E931BEC278}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WcfSample.Client", "sample\WcfSample.Client\WcfSample.Client.csproj", "{27B10A37-901E-4A3E-A2E3-4B48C62F0EB9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WcfSample.Android", "sample\WcfSample.Android\WcfSample.Android.csproj", "{A26F1176-705E-490A-ADE3-F8B12DE1D970}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebApiSample.Server", "sample\WebApiSample.Server\WebApiSample.Server.csproj", "{B993F96C-2BD3-417A-9C6B-4B3E3DDFE9B8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebApiSample.Client", "sample\WebApiSample.Client\WebApiSample.Client.csproj", "{B5473916-670C-4A84-A3B8-4D27C05AEDC2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStackSample.Client", "sample\ServiceStackSample.Client\ServiceStackSample.Client.csproj", "{AB0A2B6A-851C-4FC0-A32A-5C2F05B12EDF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStackSample.Server", "sample\ServiceStackSample.Server\ServiceStackSample.Server.csproj", "{D41E3818-D469-4F75-8AD2-D7CDE5190E4F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -35,10 +41,6 @@ Global
{68EA3E10-E607-4629-93C7-93F0AB09DCCB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{68EA3E10-E607-4629-93C7-93F0AB09DCCB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{68EA3E10-E607-4629-93C7-93F0AB09DCCB}.Release|Any CPU.Build.0 = Release|Any CPU
{4AF12B6E-9979-4146-86BC-F59F6D00E4A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4AF12B6E-9979-4146-86BC-F59F6D00E4A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4AF12B6E-9979-4146-86BC-F59F6D00E4A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4AF12B6E-9979-4146-86BC-F59F6D00E4A0}.Release|Any CPU.Build.0 = Release|Any CPU
{C43F891C-7548-4E22-B0C6-A5E931BEC278}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C43F891C-7548-4E22-B0C6-A5E931BEC278}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C43F891C-7548-4E22-B0C6-A5E931BEC278}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -48,18 +50,39 @@ Global
{27B10A37-901E-4A3E-A2E3-4B48C62F0EB9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{27B10A37-901E-4A3E-A2E3-4B48C62F0EB9}.Release|Any CPU.Build.0 = Release|Any CPU
{A26F1176-705E-490A-ADE3-F8B12DE1D970}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A26F1176-705E-490A-ADE3-F8B12DE1D970}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{A26F1176-705E-490A-ADE3-F8B12DE1D970}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A26F1176-705E-490A-ADE3-F8B12DE1D970}.Release|Any CPU.Deploy.0 = Release|Any CPU
{B993F96C-2BD3-417A-9C6B-4B3E3DDFE9B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B993F96C-2BD3-417A-9C6B-4B3E3DDFE9B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B993F96C-2BD3-417A-9C6B-4B3E3DDFE9B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B993F96C-2BD3-417A-9C6B-4B3E3DDFE9B8}.Release|Any CPU.Build.0 = Release|Any CPU
{B5473916-670C-4A84-A3B8-4D27C05AEDC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B5473916-670C-4A84-A3B8-4D27C05AEDC2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B5473916-670C-4A84-A3B8-4D27C05AEDC2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B5473916-670C-4A84-A3B8-4D27C05AEDC2}.Release|Any CPU.Build.0 = Release|Any CPU
{AB0A2B6A-851C-4FC0-A32A-5C2F05B12EDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AB0A2B6A-851C-4FC0-A32A-5C2F05B12EDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AB0A2B6A-851C-4FC0-A32A-5C2F05B12EDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AB0A2B6A-851C-4FC0-A32A-5C2F05B12EDF}.Release|Any CPU.Build.0 = Release|Any CPU
{D41E3818-D469-4F75-8AD2-D7CDE5190E4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D41E3818-D469-4F75-8AD2-D7CDE5190E4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D41E3818-D469-4F75-8AD2-D7CDE5190E4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D41E3818-D469-4F75-8AD2-D7CDE5190E4F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{6B24F793-C93B-4869-A99B-AC51EE2C82AF} = {9D5209CA-6868-45B6-A96A-C21E4318D680}
{68EA3E10-E607-4629-93C7-93F0AB09DCCB} = {7A3B0F55-40CA-46F2-9811-556FD59E67D5}
{4AF12B6E-9979-4146-86BC-F59F6D00E4A0} = {4A57BB06-6B50-4CF8-A601-E5572247FB5F}
{C43F891C-7548-4E22-B0C6-A5E931BEC278} = {4A57BB06-6B50-4CF8-A601-E5572247FB5F}
{27B10A37-901E-4A3E-A2E3-4B48C62F0EB9} = {4A57BB06-6B50-4CF8-A601-E5572247FB5F}
{A26F1176-705E-490A-ADE3-F8B12DE1D970} = {4A57BB06-6B50-4CF8-A601-E5572247FB5F}
{B993F96C-2BD3-417A-9C6B-4B3E3DDFE9B8} = {4A57BB06-6B50-4CF8-A601-E5572247FB5F}
{B5473916-670C-4A84-A3B8-4D27C05AEDC2} = {4A57BB06-6B50-4CF8-A601-E5572247FB5F}
{AB0A2B6A-851C-4FC0-A32A-5C2F05B12EDF} = {4A57BB06-6B50-4CF8-A601-E5572247FB5F}
{D41E3818-D469-4F75-8AD2-D7CDE5190E4F} = {4A57BB06-6B50-4CF8-A601-E5572247FB5F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {ADB840D9-C641-42AF-907B-8FE9280E9A8D}
Expand Down
36 changes: 18 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# InfoCarrier.Core

| branch | package | AppVeyor |
| --- | --- | --- |
| `master` | [![NuGet](https://img.shields.io/nuget/v/InfoCarrier.Core.svg?style=flat-square&label=nuget)](https://www.nuget.org/packages/InfoCarrier.Core/) | [![Build status](https://ci.appveyor.com/api/projects/status/7jd134yd7m2w035h/branch/master?svg=true)](https://ci.appveyor.com/project/azabluda/infocarrier-core/branch/master) |
| `develop` | - | [![Build status](https://ci.appveyor.com/api/projects/status/7jd134yd7m2w035h/branch/develop?svg=true)](https://ci.appveyor.com/project/azabluda/infocarrier-core/branch/develop) |
| branch | package | AppVeyor | Code Coverage |
| --- | --- | --- | --- |
| `master` | [![NuGet Badge](https://buildstats.info/nuget/InfoCarrier.Core)](http://www.nuget.org/packages/InfoCarrier.Core) | [![Build status](https://ci.appveyor.com/api/projects/status/7jd134yd7m2w035h/branch/master?svg=true)](https://ci.appveyor.com/project/azabluda/infocarrier-core/branch/master) | - |
| `develop` | - | [![Build status](https://ci.appveyor.com/api/projects/status/7jd134yd7m2w035h/branch/develop?svg=true)](https://ci.appveyor.com/project/azabluda/infocarrier-core/branch/develop) | [![codecov](https://codecov.io/gh/azabluda/InfoCarrier.Core/branch/develop/graph/badge.svg)](https://codecov.io/gh/azabluda/InfoCarrier.Core/branch/develop) |



### Description:
InfoCarrier.Core is a framework developed by [on/off it-solutions gmbh](http://www.onoff-it-solutions.info) for building multitier applications in .NET. This repository contains the key data access component of the framework which essentially is a non-relational provider for [Entity Framework Core](https://github.com/aspnet/EntityFramework) which can be deployed on the client-side of your 3-tier application allowing you to use the full power of EF.Core right in your client application (e.g. WPF, WinForms, Xamarin, UWP, etc). The main idea is that instead of querying the relational database the commands are translated into requests to your application server where they are executed against the real database.
InfoCarrier.Core is a framework developed by [on/off it-solutions gmbh](http://www.onoff-it-solutions.info) for building multi-tier applications in .NET. This repository contains the key data access component of the framework which essentially is a non-relational provider for [Entity Framework Core](https://github.com/aspnet/EntityFramework) which can be deployed on the client-side of your 3-tier application allowing you to use the full power of EF.Core right in your client application (e.g. WPF, WinForms, Xamarin, UWP, etc). The main idea is that instead of querying the relational database the commands are translated into requests to your application server where they are executed against the real database.

It is important to note that InfoCarrier.Core dictates neither the communication platform nor serialization framework. We had positive experience with [WCF](https://msdn.microsoft.com/en-us/library/ms731082.aspx) and [Json.NET](http://www.newtonsoft.com/json), but you are free to choose other frameworks and libraries. InfoCarrier.Core is only responsible for translating client commands into serializable objects, leaving it up to you how to deliver them to the server for actual execution. The same is valid for the execution results.

Expand All @@ -18,7 +18,7 @@ It is important to note that InfoCarrier.Core dictates neither the communication
* Change Tracking
* Identity Map
* Navigation Property Fix-up
* Eager/Explicit Loading of Navigation Properties
* Eager/Lazy/Explicit Loading of Navigation Properties
* etc.
* DbContext and entity classes shared between client and server, no need to duplicate this code
* Concise client-side interface `IInfoCarrierBackend`
Expand All @@ -32,7 +32,7 @@ InfoCarrier.Core is bringing together the following open source projects

## Sample

The complete WCF sample is located in the [/sample](sample) folder.
The complete WCF sample is located in the [/sample](sample) folder. There you also find simple client/server applications based on [ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/index) Web API and [ServiceStack](https://servicestack.net/) with basic support of transactions.

### Entities and DbContext

Expand All @@ -42,7 +42,7 @@ public class Blog { ... }

public class Post { ... }

public class User { ... }
public class Author { ... }

public class BloggingContext : DbContext
{
Expand All @@ -52,7 +52,7 @@ public class BloggingContext : DbContext

public DbSet<Blog> Blogs { get; set; }

public DbSet<User> Users { get; set; }
public DbSet<Author> Authors { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder) { ... }
}
Expand All @@ -64,16 +64,16 @@ Implement `IInfoCarrierBackend` interface, e.g. using Windows Communication Foun
```C#
public class WcfBackendImpl : IInfoCarrierBackend
{
private readonly ChannelFactory<IMyRemoteService> channelFactory
= new ChannelFactory<IMyRemoteService>(...);
private readonly ChannelFactory<IWcfService> channelFactory
= new ChannelFactory<IWcfService>(...);

// Gets the remote server address. Used for logging.
public string ServerUrl
=> this.channelFactory.Endpoint.Address.ToString();

public QueryDataResult QueryData(QueryDataRequest request, DbContext dbContext)
{
IMyRemoteService channel = this.channelFactory.CreateChannel();
IWcfService channel = this.channelFactory.CreateChannel();
using ((IDisposable)channel)
{
return channel.ProcessQueryDataRequest(request);
Expand All @@ -82,7 +82,7 @@ public class WcfBackendImpl : IInfoCarrierBackend

public SaveChangesResult SaveChanges(SaveChangesRequest request)
{
IMyRemoteService channel = this.channelFactory.CreateChannel();
IWcfService channel = this.channelFactory.CreateChannel();
using ((IDisposable)channel)
{
return channel.ProcessSaveChangesRequest(request);
Expand All @@ -104,8 +104,8 @@ using (var context = new BloggingContext(optionsBuilder.Options))
Post myBlogPost = (
from blog in context.Blogs
from post in blog.Posts
join owner in context.Users on blog.OwnerId equals owner.Id
where owner.login == "hi-its-me"
join author in context.Authors on blog.AuthorId equals author.Id
where author.login == "hi-its-me"
where post.Title == "my-blog-post"
select post).Single();

Expand All @@ -117,11 +117,11 @@ using (var context = new BloggingContext(optionsBuilder.Options))

### Server

Use `QueryDataHelper` and `SaveChangesHelper` classes to implement the backend service. Without transaction support it can be made very simple and virtually stateless.
Use `QueryDataHelper` and `SaveChangesHelper` classes to implement the back-end service. In the simple case when no transaction support is required it may look like the following:

```C#
[ServiceContract]
public interface IMyRemoteService
public interface IWcfService
{
[OperationContract]
QueryDataResult ProcessQueryDataRequest(QueryDataRequest request);
Expand All @@ -131,7 +131,7 @@ public interface IMyRemoteService
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class MyRemoteService : IMyRemoteService
public class InfoCarrierService : IWcfService
{
private DbContext CreateDbContext()
{
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
image: Visual Studio 2017
image: Visual Studio 2017 Preview

environment:
Test__SqlServer__DefaultConnection: Server=(local)\SQL2016;Database=master;User ID=sa;Password=Password12!
Expand Down
9 changes: 9 additions & 0 deletions coverage.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
dotnet test -f netcoreapp2.1 ^
/p:CollectCoverage=true ^
/p:CoverletOutputFormat=opencover ^
/p:CoverletOutputDirectory="%~dp0TestResults" ^
test\InfoCarrier.Core.FunctionalTests\InfoCarrier.Core.FunctionalTests.csproj

dotnet tools\ReportGenerator\ReportGenerator.dll -reports:TestResults\coverage.xml -targetdir:TestResults\coverage

start "" "TestResults\coverage\index.htm"
15 changes: 5 additions & 10 deletions sample/WcfSample.Shared/Datamodel.cs → sample/Datamodel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#pragma warning disable SA1402 // FileMayOnlyContainASingleType
#pragma warning disable SA1649 // FileNameMustMatchTypeName

namespace WcfSample
namespace InfoCarrierSample
{
using System;
using System.Collections.Generic;
Expand All @@ -14,9 +14,9 @@ public class Blog
{
public decimal Id { get; set; }

public decimal OwnerId { get; set; }
public decimal AuthorId { get; set; }

public User Owner { get; set; }
public Author Author { get; set; }

public IList<Post> Posts { get; set; }
}
Expand All @@ -34,7 +34,7 @@ public class Post
public Blog Blog { get; set; }
}

public class User
public class Author
{
public decimal Id { get; set; }

Expand All @@ -50,11 +50,6 @@ public BloggingContext(DbContextOptions options)

public DbSet<Blog> Blogs { get; set; }

public DbSet<User> Users { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Post>().ToTable("Posts");
}
public DbSet<Author> Authors { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
// Copyright (c) on/off it-solutions gmbh. All rights reserved.
// Licensed under the MIT license. See license.txt file in the project root for license information.

namespace WcfSample
namespace InfoCarrierSample
{
using System.ServiceModel;
using System.Threading.Tasks;
using InfoCarrier.Core.Common;

[ServiceContract]
public interface IMyRemoteService
public interface IWcfService
{
[OperationContract]
QueryDataResult ProcessQueryDataRequest(QueryDataRequest request);

[OperationContract(Name = "ProcessQueryDataRequestAsync")]
[OperationContract(Name = nameof(ProcessQueryDataRequestAsync))]
Task<QueryDataResult> ProcessQueryDataRequestAsync(QueryDataRequest request);

[OperationContract]
SaveChangesResult ProcessSaveChangesRequest(SaveChangesRequest request);

[OperationContract(Name = "ProcessSaveChangesRequestAsync")]
[OperationContract(Name = nameof(ProcessSaveChangesRequestAsync))]
Task<SaveChangesResult> ProcessSaveChangesRequestAsync(SaveChangesRequest request);
}
}
Loading

0 comments on commit 5e8503a

Please sign in to comment.