├── .gitattributes
├── .gitignore
├── .nuget
├── NuGet.Config
├── NuGet.exe
└── NuGet.targets
├── CreateDatabaseTables.sql
├── CreateLocalDatabase.sql
├── LICENCE.md
├── MarketFinder.AnalyticsService
├── MarketFinder.AnalyticsService.csproj
├── MarketsDataRepository.cs
├── Properties
│ └── AssemblyInfo.cs
├── Rating.cs
├── RecomendationRepository.cs
├── RecommendationsAnalysisController.cs
└── packages.config
├── MarketFinder.CommonHost
├── App_Start
│ └── WebApiConfig.cs
├── Global.asax
├── Global.asax.cs
├── MarketFinder.CommonHost.csproj
├── Properties
│ └── AssemblyInfo.cs
├── Web.Debug.config
├── Web.Release.config
├── Web.config
└── packages.config
├── MarketFinder.MakretManagementService
├── App.config
├── Controllers
│ ├── MarketsController.cs
│ └── RatingsController.cs
├── MarketFinder.MakretManagementService.csproj
├── Models
│ ├── Market.cs
│ ├── MarketManagementServiceContext.cs
│ └── Rating.cs
├── Properties
│ └── AssemblyInfo.cs
└── packages.config
├── MarketFinder.sln
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | bin
2 | obj
3 | *.user
4 | *.suo
5 | /packages
--------------------------------------------------------------------------------
/.nuget/NuGet.Config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.nuget/NuGet.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kszabelski/Microservices---ASP.NET-Web-API---Azure/5c49b862f80dacac68cb93a9c01b3395885f6499/.nuget/NuGet.exe
--------------------------------------------------------------------------------
/.nuget/NuGet.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MSBuildProjectDirectory)\..\
5 |
6 |
7 | false
8 |
9 |
10 | false
11 |
12 |
13 | true
14 |
15 |
16 | false
17 |
18 |
19 |
20 |
21 |
22 |
26 |
27 |
28 |
29 |
30 | $([System.IO.Path]::Combine($(SolutionDir), ".nuget"))
31 |
32 |
33 |
34 |
35 | $(SolutionDir).nuget
36 |
37 |
38 |
39 | $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName.Replace(' ', '_')).config
40 | $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName).config
41 |
42 |
43 |
44 | $(MSBuildProjectDirectory)\packages.config
45 | $(PackagesProjectConfig)
46 |
47 |
48 |
49 |
50 | $(NuGetToolsPath)\NuGet.exe
51 | @(PackageSource)
52 |
53 | "$(NuGetExePath)"
54 | mono --runtime=v4.0.30319 "$(NuGetExePath)"
55 |
56 | $(TargetDir.Trim('\\'))
57 |
58 | -RequireConsent
59 | -NonInteractive
60 |
61 | "$(SolutionDir) "
62 | "$(SolutionDir)"
63 |
64 |
65 | $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)
66 | $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols
67 |
68 |
69 |
70 | RestorePackages;
71 | $(BuildDependsOn);
72 |
73 |
74 |
75 |
76 | $(BuildDependsOn);
77 | BuildPackage;
78 |
79 |
80 |
81 |
82 |
83 |
84 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
99 |
100 |
103 |
104 |
105 |
106 |
108 |
109 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
141 |
142 |
143 |
144 |
145 |
--------------------------------------------------------------------------------
/CreateDatabaseTables.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE [dbo].[Markets](
2 | [Id] [int] IDENTITY(1,1) NOT NULL,
3 | [Name] [nvarchar](max) NULL,
4 | [Address] [nvarchar](max) NULL,
5 | [Notes] [nvarchar](max) NULL,
6 | CONSTRAINT [PK_dbo.Markets] PRIMARY KEY CLUSTERED
7 | (
8 | [Id] ASC
9 | )
10 | )
11 | GO
12 |
13 | CREATE TABLE [dbo].[Ratings](
14 | [Id] [int] IDENTITY(1,1) NOT NULL,
15 | [UserEmail] [nvarchar](max) NULL,
16 | [Comment] [nvarchar](max) NULL,
17 | [Rate] [int] NOT NULL,
18 | [MarketId] [int] NOT NULL,
19 | CONSTRAINT [PK_dbo.Ratings] PRIMARY KEY CLUSTERED
20 | (
21 | [Id] ASC
22 | )
23 | )
24 | GO
25 |
26 | CREATE TABLE [dbo].[Recommendations](
27 | [Id] [int] IDENTITY(1,1) NOT NULL,
28 | [UserEmail] [nvarchar](max) NOT NULL,
29 | [MarketId] [int] NOT NULL,
30 | CONSTRAINT [PK_Recommendations] PRIMARY KEY CLUSTERED
31 | (
32 | [Id] ASC
33 | )
34 | )
35 | GO
--------------------------------------------------------------------------------
/CreateLocalDatabase.sql:
--------------------------------------------------------------------------------
1 | CREATE DATABASE [MarketManagementServiceDb]
2 | GO
3 |
--------------------------------------------------------------------------------
/LICENCE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Future Processing Sp. z o.o.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/MarketFinder.AnalyticsService/MarketFinder.AnalyticsService.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {6D2BAC0F-6460-4EC6-9105-58A006ECAD86}
8 | Library
9 | Properties
10 | MarketFinder.AnalyticsService
11 | MarketFinder.AnalyticsService
12 | v4.5
13 | 512
14 | ..\
15 | true
16 |
17 |
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 | ..\packages\Dapper.1.42\lib\net45\Dapper.dll
37 |
38 |
39 | False
40 | ..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
41 |
42 |
43 |
44 |
45 |
46 |
47 | False
48 | ..\packages\Microsoft.AspNet.WebApi.Client.5.2.2\lib\net45\System.Net.Http.Formatting.dll
49 |
50 |
51 | False
52 | ..\packages\Microsoft.AspNet.WebApi.Core.5.2.2\lib\net45\System.Web.Http.dll
53 |
54 |
55 | False
56 | ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.2\lib\net45\System.Web.Http.WebHost.dll
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
79 |
80 |
81 |
82 |
89 |
--------------------------------------------------------------------------------
/MarketFinder.AnalyticsService/MarketsDataRepository.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Configuration;
3 | using System.Data.SqlClient;
4 | using Dapper;
5 |
6 | namespace MarketFinder.AnalyticsService
7 | {
8 | public class MarketsDataRepository
9 | {
10 | public IEnumerable GetRatings()
11 | {
12 | string connectionString = ConfigurationManager.ConnectionStrings["MarketManagementServiceDb"].ConnectionString;
13 | using (var connection = new SqlConnection(connectionString))
14 | {
15 | return connection.Query("SELECT * FROM Ratings");
16 | }
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/MarketFinder.AnalyticsService/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("MarketFinder.AnalyticsService")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("MarketFinder.AnalyticsService")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("d169af8b-e524-4335-90a1-c23cb947efdb")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/MarketFinder.AnalyticsService/Rating.cs:
--------------------------------------------------------------------------------
1 | namespace MarketFinder.AnalyticsService
2 | {
3 | public class Rating
4 | {
5 | public int Id { get; set; }
6 |
7 | public string UserEmail { get; set; }
8 |
9 | public string Comment { get; set; }
10 |
11 | public int Rate { get; set; }
12 |
13 | public int MarketId { get; set; }
14 | }
15 | }
--------------------------------------------------------------------------------
/MarketFinder.AnalyticsService/RecomendationRepository.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Configuration;
3 | using System.Data.SqlClient;
4 | using Dapper;
5 |
6 | namespace MarketFinder.AnalyticsService
7 | {
8 | public class RecomendationRepository
9 | {
10 | public void Insert(string userEmail, int marketId)
11 | {
12 | string connectionString = ConfigurationManager.ConnectionStrings["RecommendationsDb"].ConnectionString;
13 | using (var connection = new SqlConnection(connectionString))
14 | {
15 | connection.Execute(
16 | "INSERT Recommendations (UserEmail, MarketId) VALUES (@userEmail, @marketId)",
17 | new { userEmail, marketId});
18 | }
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/MarketFinder.AnalyticsService/RecommendationsAnalysisController.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Configuration;
3 | using System.Data.SqlClient;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Web.Http;
8 | using Dapper;
9 |
10 | namespace MarketFinder.AnalyticsService
11 | {
12 | public class RecommendationsAnalysisController : ApiController
13 | {
14 | private readonly MarketsDataRepository _marketsDataRepository = new MarketsDataRepository();
15 | private readonly RecomendationRepository _recomendationRepository = new RecomendationRepository();
16 |
17 | [HttpPost]
18 | public void GenerateRecomendations()
19 | {
20 | var ratings = _marketsDataRepository.GetRatings();
21 |
22 | var userToFavouriteMarkets = new Dictionary>();
23 | var userRatings = ratings.GroupBy(r=>r.UserEmail);
24 | foreach (var userRating in userRatings)
25 | {
26 | userToFavouriteMarkets[userRating.Key] = userRating.OrderByDescending(r => r.Rate).Take(3).Select(r => r.MarketId).ToList();
27 | }
28 |
29 | foreach (var userRating in userRatings)
30 | {
31 | var userFavourites = userRating.OrderByDescending(r => r.Rate).Take(5).Select(r => r.MarketId).ToArray();
32 | var usersWithSimilarRecommendations = userToFavouriteMarkets.Select(u=>u.Value).Where(ufm => ufm.Any(r => userFavourites.Contains(r)));
33 |
34 | var userRecomendations = usersWithSimilarRecommendations.SelectMany(u => u).Distinct().Except(userRating.Select(u=>u.MarketId)).ToList();
35 |
36 | foreach (var userRecomendation in userRecomendations)
37 | {
38 | _recomendationRepository.Insert(userRating.Key, userRecomendation);
39 | }
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/MarketFinder.AnalyticsService/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/MarketFinder.CommonHost/App_Start/WebApiConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Web.Http;
5 |
6 | namespace MarketFinder.CommonHost
7 | {
8 | public static class WebApiConfig
9 | {
10 | public static void Register(HttpConfiguration config)
11 | {
12 | // Web API configuration and services
13 |
14 | // Web API routes
15 | config.MapHttpAttributeRoutes();
16 |
17 | config.Routes.MapHttpRoute(
18 | name: "DefaultApi",
19 | routeTemplate: "{controller}/{id}",
20 | defaults: new { id = RouteParameter.Optional }
21 | );
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/MarketFinder.CommonHost/Global.asax:
--------------------------------------------------------------------------------
1 | <%@ Application Codebehind="Global.asax.cs" Inherits="MarketFinder.CommonHost.WebApiApplication" Language="C#" %>
2 |
--------------------------------------------------------------------------------
/MarketFinder.CommonHost/Global.asax.cs:
--------------------------------------------------------------------------------
1 | using System.Web;
2 | using System.Web.Http;
3 |
4 | namespace MarketFinder.CommonHost
5 | {
6 | public class WebApiApplication : HttpApplication
7 | {
8 | protected void Application_Start()
9 | {
10 | GlobalConfiguration.Configure(WebApiConfig.Register);
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/MarketFinder.CommonHost/MarketFinder.CommonHost.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 |
8 |
9 | 2.0
10 | {3D7B8032-D376-4973-8864-AB5D56741C8B}
11 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
12 | Library
13 | Properties
14 | MarketFinder.CommonHost
15 | MarketFinder.CommonHost
16 | v4.5
17 | true
18 |
19 |
20 |
21 |
22 | ..\
23 | true
24 |
25 |
26 | true
27 | full
28 | false
29 | bin\
30 | DEBUG;TRACE
31 | prompt
32 | 4
33 |
34 |
35 | pdbonly
36 | true
37 | bin\
38 | TRACE
39 | prompt
40 | 4
41 |
42 |
43 |
44 | False
45 | ..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.dll
46 |
47 |
48 | ..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | ..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
72 |
73 |
74 | ..\packages\Microsoft.AspNet.WebApi.Client.5.2.2\lib\net45\System.Net.Http.Formatting.dll
75 |
76 |
77 | ..\packages\Microsoft.AspNet.WebApi.Core.5.2.2\lib\net45\System.Web.Http.dll
78 |
79 |
80 | ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.2\lib\net45\System.Web.Http.WebHost.dll
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 | Global.asax
91 |
92 |
93 |
94 |
95 |
96 | Designer
97 |
98 |
99 | Web.config
100 |
101 |
102 | Web.config
103 |
104 |
105 |
106 |
107 |
108 | {6d2bac0f-6460-4ec6-9105-58a006ecad86}
109 | MarketFinder.AnalyticsService
110 |
111 |
112 | {cefe6fb1-4575-43b8-a065-0f098186d5c7}
113 | MarketFinder.MakretManagementService
114 |
115 |
116 |
117 | 10.0
118 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 | True
128 | True
129 | 24043
130 | /
131 | http://localhost:24043/
132 | False
133 | False
134 |
135 |
136 | False
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 | This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
145 |
146 |
147 |
148 |
155 |
--------------------------------------------------------------------------------
/MarketFinder.CommonHost/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("MarketFinder.CommonHost")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("MarketFinder.CommonHost")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("82e4482c-67a0-4511-a0c8-043de07deb43")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Revision and Build Numbers
33 | // by using the '*' as shown below:
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/MarketFinder.CommonHost/Web.Debug.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
18 |
29 |
30 |
--------------------------------------------------------------------------------
/MarketFinder.CommonHost/Web.Release.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
18 |
19 |
30 |
31 |
--------------------------------------------------------------------------------
/MarketFinder.CommonHost/Web.config:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/MarketFinder.CommonHost/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/MarketFinder.MakretManagementService/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/MarketFinder.MakretManagementService/Controllers/MarketsController.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Data.Entity;
3 | using System.Data.Entity.Infrastructure;
4 | using System.Linq;
5 | using System.Net;
6 | using System.Threading.Tasks;
7 | using System.Web.Http;
8 | using System.Web.Http.Description;
9 | using MarketFinder.MakretManagementService.Models;
10 |
11 | namespace MarketFinder.MakretManagementService.Controllers
12 | {
13 | public class MarketsController : ApiController
14 | {
15 | private MarketManagementServiceContext db = new MarketManagementServiceContext();
16 |
17 | // GET: Markets
18 | public async Task> GetMarkets()
19 | {
20 | return await db.Markets.ToListAsync();
21 | }
22 |
23 | // GET: Markets/5
24 | [ResponseType(typeof(Market))]
25 | public async Task GetMarket(int id)
26 | {
27 | Market market = await db.Markets.FindAsync(id);
28 | if (market == null)
29 | {
30 | return NotFound();
31 | }
32 |
33 | return Ok(market);
34 | }
35 |
36 | // PUT: Markets/5
37 | [ResponseType(typeof(void))]
38 | public async Task PutMarket(int id, [FromBody]Market market)
39 | {
40 | if (!ModelState.IsValid)
41 | {
42 | return BadRequest(ModelState);
43 | }
44 |
45 | if (id != market.Id)
46 | {
47 | return BadRequest();
48 | }
49 |
50 | db.Entry(market).State = EntityState.Modified;
51 |
52 | try
53 | {
54 | await db.SaveChangesAsync();
55 | }
56 | catch (DbUpdateConcurrencyException)
57 | {
58 | if (!MarketExists(id))
59 | {
60 | return NotFound();
61 | }
62 | else
63 | {
64 | throw;
65 | }
66 | }
67 |
68 | return StatusCode(HttpStatusCode.NoContent);
69 | }
70 |
71 | // POST: Markets
72 | [ResponseType(typeof(Market))]
73 | public async Task PostMarket(Market market)
74 | {
75 | if (!ModelState.IsValid)
76 | {
77 | return BadRequest(ModelState);
78 | }
79 |
80 | db.Markets.Add(market);
81 | await db.SaveChangesAsync();
82 |
83 | return CreatedAtRoute("DefaultApi", new { id = market.Id }, market);
84 | }
85 |
86 | // DELETE: Markets/5
87 | [ResponseType(typeof(Market))]
88 | public async Task DeleteMarket(int id)
89 | {
90 | Market market = await db.Markets.FindAsync(id);
91 | if (market == null)
92 | {
93 | return NotFound();
94 | }
95 |
96 | db.Markets.Remove(market);
97 | await db.SaveChangesAsync();
98 |
99 | return Ok(market);
100 | }
101 |
102 | protected override void Dispose(bool disposing)
103 | {
104 | if (disposing)
105 | {
106 | db.Dispose();
107 | }
108 | base.Dispose(disposing);
109 | }
110 |
111 | private bool MarketExists(int id)
112 | {
113 | return db.Markets.Count(e => e.Id == id) > 0;
114 | }
115 | }
116 | }
--------------------------------------------------------------------------------
/MarketFinder.MakretManagementService/Controllers/RatingsController.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Data.Entity;
3 | using System.Data.Entity.Infrastructure;
4 | using System.Linq;
5 | using System.Net;
6 | using System.Threading.Tasks;
7 | using System.Web.Http;
8 | using System.Web.Http.Description;
9 | using MarketFinder.MakretManagementService.Models;
10 |
11 | namespace MarketFinder.MakretManagementService.Controllers
12 | {
13 | public class RatingsController : ApiController
14 | {
15 | private MarketManagementServiceContext db = new MarketManagementServiceContext();
16 |
17 | // GET: Ratings
18 | public async Task> GetRatings()
19 | {
20 | return await db.Ratings.ToListAsync();
21 | }
22 |
23 | // GET: Ratings/5
24 | [ResponseType(typeof(Rating))]
25 | public async Task GetRating(int id)
26 | {
27 | Rating rating = await db.Ratings.FindAsync(id);
28 | if (rating == null)
29 | {
30 | return NotFound();
31 | }
32 |
33 | return Ok(rating);
34 | }
35 |
36 | // PUT: Ratings/5
37 | [ResponseType(typeof(void))]
38 | public async Task PutRating(int id, Rating rating)
39 | {
40 | if (!ModelState.IsValid)
41 | {
42 | return BadRequest(ModelState);
43 | }
44 |
45 | if (id != rating.Id)
46 | {
47 | return BadRequest();
48 | }
49 |
50 | db.Entry(rating).State = EntityState.Modified;
51 |
52 | try
53 | {
54 | await db.SaveChangesAsync();
55 | }
56 | catch (DbUpdateConcurrencyException)
57 | {
58 | if (!RatingExists(id))
59 | {
60 | return NotFound();
61 | }
62 | else
63 | {
64 | throw;
65 | }
66 | }
67 |
68 | return StatusCode(HttpStatusCode.NoContent);
69 | }
70 |
71 | // POST: Ratings
72 | [ResponseType(typeof(Rating))]
73 | public async Task PostRating(Rating rating)
74 | {
75 | if (!ModelState.IsValid)
76 | {
77 | return BadRequest(ModelState);
78 | }
79 |
80 | db.Ratings.Add(rating);
81 | await db.SaveChangesAsync();
82 |
83 | return CreatedAtRoute("DefaultApi", new { id = rating.Id }, rating);
84 | }
85 |
86 | // DELETE: Ratings/5
87 | [ResponseType(typeof(Rating))]
88 | public async Task DeleteRating(int id)
89 | {
90 | Rating rating = await db.Ratings.FindAsync(id);
91 | if (rating == null)
92 | {
93 | return NotFound();
94 | }
95 |
96 | db.Ratings.Remove(rating);
97 | await db.SaveChangesAsync();
98 |
99 | return Ok(rating);
100 | }
101 |
102 | protected override void Dispose(bool disposing)
103 | {
104 | if (disposing)
105 | {
106 | db.Dispose();
107 | }
108 | base.Dispose(disposing);
109 | }
110 |
111 | private bool RatingExists(int id)
112 | {
113 | return db.Ratings.Count(e => e.Id == id) > 0;
114 | }
115 | }
116 | }
--------------------------------------------------------------------------------
/MarketFinder.MakretManagementService/MarketFinder.MakretManagementService.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {CEFE6FB1-4575-43B8-A065-0F098186D5C7}
8 | Library
9 | Properties
10 | MarketFinder.MakretManagementService
11 | MarketFinder.MakretManagementService
12 | v4.5
13 | 512
14 | ..\
15 | true
16 |
17 |
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 | False
37 | ..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.dll
38 |
39 |
40 | False
41 | ..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll
42 |
43 |
44 | False
45 | ..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
46 |
47 |
48 |
49 |
50 |
51 |
52 | False
53 | ..\packages\Microsoft.AspNet.WebApi.Client.5.2.2\lib\net45\System.Net.Http.Formatting.dll
54 |
55 |
56 | False
57 | ..\packages\Microsoft.AspNet.WebApi.Core.5.2.2\lib\net45\System.Web.Http.dll
58 |
59 |
60 | False
61 | ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.2\lib\net45\System.Web.Http.WebHost.dll
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 | This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
86 |
87 |
88 |
89 |
96 |
--------------------------------------------------------------------------------
/MarketFinder.MakretManagementService/Models/Market.cs:
--------------------------------------------------------------------------------
1 | namespace MarketFinder.MakretManagementService.Models
2 | {
3 | public class Market
4 | {
5 | public int? Id { get; set; }
6 |
7 | public string Name { get; set; }
8 |
9 | public string Address { get; set; }
10 |
11 | public string Notes { get; set; }
12 | }
13 | }
--------------------------------------------------------------------------------
/MarketFinder.MakretManagementService/Models/MarketManagementServiceContext.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Data.Entity;
3 |
4 | namespace MarketFinder.MakretManagementService.Models
5 | {
6 | public class MarketManagementServiceContext : DbContext
7 | {
8 | static MarketManagementServiceContext()
9 | {
10 | // Use CreateDatabase.sql to create Database
11 | Database.SetInitializer(null);
12 | }
13 |
14 | public MarketManagementServiceContext()
15 | : base("name=MarketManagementServiceDb")
16 | {
17 | }
18 |
19 | public System.Data.Entity.DbSet Markets { get; set; }
20 |
21 | public System.Data.Entity.DbSet Ratings { get; set; }
22 |
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/MarketFinder.MakretManagementService/Models/Rating.cs:
--------------------------------------------------------------------------------
1 | namespace MarketFinder.MakretManagementService.Models
2 | {
3 | public class Rating
4 | {
5 | public int Id { get; set; }
6 |
7 | public string UserEmail { get; set; }
8 |
9 | public string Comment { get; set; }
10 |
11 | public int Rate { get; set; }
12 |
13 | // For simplicity of this demo code it lacks Forign Key here
14 | public int MarketId { get; set; }
15 | }
16 | }
--------------------------------------------------------------------------------
/MarketFinder.MakretManagementService/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("MarketFinder.MakretManagementService")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("MarketFinder.MakretManagementService")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("c99e758d-a407-48fc-86bd-fb34fc270373")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/MarketFinder.MakretManagementService/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/MarketFinder.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.31101.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MarketFinder.MakretManagementService", "MarketFinder.MakretManagementService\MarketFinder.MakretManagementService.csproj", "{CEFE6FB1-4575-43B8-A065-0F098186D5C7}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{80CB27D5-E79D-47A7-9CD3-709D464DBDD0}"
9 | ProjectSection(SolutionItems) = preProject
10 | .nuget\NuGet.Config = .nuget\NuGet.Config
11 | .nuget\NuGet.exe = .nuget\NuGet.exe
12 | .nuget\NuGet.targets = .nuget\NuGet.targets
13 | EndProjectSection
14 | EndProject
15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MarketFinder.CommonHost", "MarketFinder.CommonHost\MarketFinder.CommonHost.csproj", "{3D7B8032-D376-4973-8864-AB5D56741C8B}"
16 | EndProject
17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MarketFinder.AnalyticsService", "MarketFinder.AnalyticsService\MarketFinder.AnalyticsService.csproj", "{6D2BAC0F-6460-4EC6-9105-58A006ECAD86}"
18 | EndProject
19 | Global
20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
21 | Debug|Any CPU = Debug|Any CPU
22 | Release|Any CPU = Release|Any CPU
23 | EndGlobalSection
24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
25 | {CEFE6FB1-4575-43B8-A065-0F098186D5C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26 | {CEFE6FB1-4575-43B8-A065-0F098186D5C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
27 | {CEFE6FB1-4575-43B8-A065-0F098186D5C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
28 | {CEFE6FB1-4575-43B8-A065-0F098186D5C7}.Release|Any CPU.Build.0 = Release|Any CPU
29 | {3D7B8032-D376-4973-8864-AB5D56741C8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30 | {3D7B8032-D376-4973-8864-AB5D56741C8B}.Debug|Any CPU.Build.0 = Debug|Any CPU
31 | {3D7B8032-D376-4973-8864-AB5D56741C8B}.Release|Any CPU.ActiveCfg = Release|Any CPU
32 | {3D7B8032-D376-4973-8864-AB5D56741C8B}.Release|Any CPU.Build.0 = Release|Any CPU
33 | {6D2BAC0F-6460-4EC6-9105-58A006ECAD86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34 | {6D2BAC0F-6460-4EC6-9105-58A006ECAD86}.Debug|Any CPU.Build.0 = Debug|Any CPU
35 | {6D2BAC0F-6460-4EC6-9105-58A006ECAD86}.Release|Any CPU.ActiveCfg = Release|Any CPU
36 | {6D2BAC0F-6460-4EC6-9105-58A006ECAD86}.Release|Any CPU.Build.0 = Release|Any CPU
37 | EndGlobalSection
38 | GlobalSection(SolutionProperties) = preSolution
39 | HideSolutionNode = FALSE
40 | EndGlobalSection
41 | EndGlobal
42 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Microservices - ASP.NET Web API - Azure
2 |
3 | This is sample project presenting how to organize system into multiple lightweight, logical, decoupled components, rather that multiple independently hosted services. With this approach we can start with hosting all components in single service and dividing it into multiple ones overtime.
4 |
5 | This code is related to article posted at [Future Processing technical blog](http://www.future-processing.pl/technical-blog/).
6 |
7 | ---
8 | Krzysztof Szabelski
9 | http://krzysztofszabelski.com/
10 |
--------------------------------------------------------------------------------