@ -0,0 +1,184 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||||
<PropertyGroup> | |||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | |||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | |||||
<ProductVersion>8.0.30703</ProductVersion> | |||||
<SchemaVersion>2.0</SchemaVersion> | |||||
<ProjectGuid>{A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}</ProjectGuid> | |||||
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | |||||
<OutputType>Library</OutputType> | |||||
<AppDesignerFolder>Properties</AppDesignerFolder> | |||||
<RootNamespace>eShopOnContainers.TestRunner.Droid</RootNamespace> | |||||
<AssemblyName>eShopOnContainers.TestRunner.Droid</AssemblyName> | |||||
<FileAlignment>512</FileAlignment> | |||||
<AndroidApplication>true</AndroidApplication> | |||||
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile> | |||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> | |||||
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk> | |||||
<TargetFrameworkVersion>v7.0</TargetFrameworkVersion> | |||||
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest> | |||||
<NuGetPackageImportStamp> | |||||
</NuGetPackageImportStamp> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | |||||
<DebugSymbols>true</DebugSymbols> | |||||
<DebugType>full</DebugType> | |||||
<Optimize>false</Optimize> | |||||
<OutputPath>bin\Debug\</OutputPath> | |||||
<DefineConstants>DEBUG;TRACE</DefineConstants> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<AndroidUseSharedRuntime>True</AndroidUseSharedRuntime> | |||||
<AndroidLinkMode>None</AndroidLinkMode> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | |||||
<DebugType>pdbonly</DebugType> | |||||
<DebugSymbols>true</DebugSymbols> | |||||
<AndroidManagedSymbols>true</AndroidManagedSymbols> | |||||
<Optimize>true</Optimize> | |||||
<OutputPath>bin\Release\</OutputPath> | |||||
<DefineConstants>TRACE</DefineConstants> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime> | |||||
<AndroidLinkMode>SdkOnly</AndroidLinkMode> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<Reference Include="FormsViewGroup, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\Xamarin.Forms.2.3.3.166-pre4\lib\MonoAndroid10\FormsViewGroup.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Mono.Android" /> | |||||
<Reference Include="mscorlib" /> | |||||
<Reference Include="System" /> | |||||
<Reference Include="System.Core" /> | |||||
<Reference Include="System.Xml.Linq" /> | |||||
<Reference Include="System.Xml" /> | |||||
<Reference Include="Xamarin.Android.Support.Animated.Vector.Drawable, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.Animated.Vector.Drawable.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.Design, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\Xamarin.Android.Support.Design.23.3.0\lib\MonoAndroid43\Xamarin.Android.Support.Design.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.v4, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\Xamarin.Android.Support.v4.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v4.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.v7.AppCompat, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\Xamarin.Android.Support.v7.AppCompat.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.AppCompat.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.v7.CardView, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\Xamarin.Android.Support.v7.CardView.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.CardView.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.v7.MediaRouter, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\Xamarin.Android.Support.v7.MediaRouter.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.MediaRouter.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.v7.RecyclerView, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\Xamarin.Android.Support.v7.RecyclerView.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.RecyclerView.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.Vector.Drawable, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\Xamarin.Android.Support.Vector.Drawable.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.Vector.Drawable.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Forms.Core, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\Xamarin.Forms.2.3.3.166-pre4\lib\MonoAndroid10\Xamarin.Forms.Core.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Forms.Platform, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\Xamarin.Forms.2.3.3.166-pre4\lib\MonoAndroid10\Xamarin.Forms.Platform.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Forms.Platform.Android, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\Xamarin.Forms.2.3.3.166-pre4\lib\MonoAndroid10\Xamarin.Forms.Platform.Android.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Forms.Xaml, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\Xamarin.Forms.2.3.3.166-pre4\lib\MonoAndroid10\Xamarin.Forms.Xaml.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\xunit.abstractions.2.0.1\lib\netstandard1.0\xunit.abstractions.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="xunit.assert, Version=2.2.0.3444, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\xunit.assert.2.2.0-beta4-build3444\lib\netstandard1.0\xunit.assert.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="xunit.core, Version=2.2.0.3444, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\xunit.extensibility.core.2.2.0-beta4-build3444\lib\netstandard1.0\xunit.core.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="xunit.execution.dotnet, Version=2.2.0.3444, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\xunit.extensibility.execution.2.2.0-beta4-build3444\lib\netstandard1.0\xunit.execution.dotnet.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="xunit.runner.devices, Version=2.1.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\xunit.runner.devices.2.1.0\lib\MonoAndroid\xunit.runner.devices.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="xunit.runner.utility.dotnet, Version=2.2.0.3444, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\xunit.runner.utility.2.2.0-beta4-build3444\lib\netstandard1.1\xunit.runner.utility.dotnet.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<Compile Include="MainActivity.cs" /> | |||||
<Compile Include="Resources\Resource.Designer.cs" /> | |||||
<Compile Include="Properties\AssemblyInfo.cs" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<None Include="app.config" /> | |||||
<None Include="packages.config" /> | |||||
<None Include="Resources\AboutResources.txt" /> | |||||
<None Include="Assets\AboutAssets.txt" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\layout\Main.axml"> | |||||
<SubType>Designer</SubType> | |||||
</AndroidResource> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\values\Strings.xml" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable\Icon.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<None Include="Properties\AndroidManifest.xml" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<Content Include="MainActivity.cs.txt" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<ProjectReference Include="..\eShopOnContainers.UnitTests\eShopOnContainers.UnitTests.csproj"> | |||||
<Project>{f7b6a162-bc4d-4924-b16a-713f9b0344e7}</Project> | |||||
<Name>eShopOnContainers.UnitTests</Name> | |||||
</ProjectReference> | |||||
</ItemGroup> | |||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" /> | |||||
<Import Project="..\..\packages\Xamarin.Android.Support.Vector.Drawable.23.3.0\build\Xamarin.Android.Support.Vector.Drawable.targets" Condition="Exists('..\..\packages\Xamarin.Android.Support.Vector.Drawable.23.3.0\build\Xamarin.Android.Support.Vector.Drawable.targets')" /> | |||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> | |||||
<PropertyGroup> | |||||
<ErrorText>Este proyecto hace referencia a los paquetes NuGet que faltan en este equipo. Use la restauración de paquetes NuGet para descargarlos. Para obtener más información, consulte http://go.microsoft.com/fwlink/?LinkID=322105. El archivo que falta es {0}.</ErrorText> | |||||
</PropertyGroup> | |||||
<Error Condition="!Exists('..\..\packages\Xamarin.Android.Support.Vector.Drawable.23.3.0\build\Xamarin.Android.Support.Vector.Drawable.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Xamarin.Android.Support.Vector.Drawable.23.3.0\build\Xamarin.Android.Support.Vector.Drawable.targets'))" /> | |||||
<Error Condition="!Exists('..\..\packages\Xamarin.Forms.2.3.3.166-pre4\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Xamarin.Forms.2.3.3.166-pre4\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets'))" /> | |||||
<Error Condition="!Exists('..\..\packages\xunit.runner.devices.2.1.0\build\MonoAndroid\xunit.runner.devices.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\xunit.runner.devices.2.1.0\build\MonoAndroid\xunit.runner.devices.targets'))" /> | |||||
</Target> | |||||
<Import Project="..\..\packages\Xamarin.Forms.2.3.3.166-pre4\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets" Condition="Exists('..\..\packages\Xamarin.Forms.2.3.3.166-pre4\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets')" /> | |||||
<Import Project="..\..\packages\xunit.runner.devices.2.1.0\build\MonoAndroid\xunit.runner.devices.targets" Condition="Exists('..\..\packages\xunit.runner.devices.2.1.0\build\MonoAndroid\xunit.runner.devices.targets')" /> | |||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. | |||||
Other similar extension points exist, see Microsoft.Common.targets. | |||||
<Target Name="BeforeBuild"> | |||||
</Target> | |||||
<Target Name="AfterBuild"> | |||||
</Target> | |||||
--> | |||||
</Project> |
@ -0,0 +1,175 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||||
<PropertyGroup> | |||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | |||||
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform> | |||||
<ProjectGuid>{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}</ProjectGuid> | |||||
<ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | |||||
<OutputType>Exe</OutputType> | |||||
<RootNamespace>eShopOnContainers.TestRunner.iOS</RootNamespace> | |||||
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix> | |||||
<AssemblyName>eShopOnContainers.TestRunner.iOS</AssemblyName> | |||||
<NuGetPackageImportStamp> | |||||
</NuGetPackageImportStamp> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' "> | |||||
<DebugSymbols>true</DebugSymbols> | |||||
<DebugType>full</DebugType> | |||||
<Optimize>false</Optimize> | |||||
<OutputPath>bin\iPhoneSimulator\Debug</OutputPath> | |||||
<DefineConstants>DEBUG</DefineConstants> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<ConsolePause>false</ConsolePause> | |||||
<MtouchArch>x86_64</MtouchArch> | |||||
<MtouchLink>SdkOnly</MtouchLink> | |||||
<MtouchDebug>True</MtouchDebug> | |||||
<MtouchSdkVersion>10.1</MtouchSdkVersion> | |||||
<MtouchProfiling>False</MtouchProfiling> | |||||
<MtouchFastDev>False</MtouchFastDev> | |||||
<MtouchUseLlvm>False</MtouchUseLlvm> | |||||
<MtouchUseThumb>False</MtouchUseThumb> | |||||
<MtouchEnableBitcode>False</MtouchEnableBitcode> | |||||
<MtouchUseSGen>False</MtouchUseSGen> | |||||
<MtouchUseRefCounting>False</MtouchUseRefCounting> | |||||
<OptimizePNGs>True</OptimizePNGs> | |||||
<MtouchTlsProvider>Default</MtouchTlsProvider> | |||||
<MtouchHttpClientHandler>HttpClientHandler</MtouchHttpClientHandler> | |||||
<MtouchFloat32>False</MtouchFloat32> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' "> | |||||
<DebugType>none</DebugType> | |||||
<Optimize>true</Optimize> | |||||
<OutputPath>bin\iPhoneSimulator\Release</OutputPath> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<MtouchLink>None</MtouchLink> | |||||
<MtouchArch>x86_64</MtouchArch> | |||||
<ConsolePause>false</ConsolePause> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' "> | |||||
<DebugSymbols>true</DebugSymbols> | |||||
<DebugType>full</DebugType> | |||||
<Optimize>false</Optimize> | |||||
<OutputPath>bin\iPhone\Debug</OutputPath> | |||||
<DefineConstants>DEBUG</DefineConstants> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<ConsolePause>false</ConsolePause> | |||||
<MtouchArch>ARMv7, ARM64</MtouchArch> | |||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements> | |||||
<CodesignKey>iPhone Developer</CodesignKey> | |||||
<MtouchDebug>true</MtouchDebug> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' "> | |||||
<DebugType>none</DebugType> | |||||
<Optimize>true</Optimize> | |||||
<OutputPath>bin\iPhone\Release</OutputPath> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements> | |||||
<MtouchArch>ARMv7, ARM64</MtouchArch> | |||||
<ConsolePause>false</ConsolePause> | |||||
<CodesignKey>iPhone Developer</CodesignKey> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Ad-Hoc|iPhone' "> | |||||
<DebugType>none</DebugType> | |||||
<Optimize>True</Optimize> | |||||
<OutputPath>bin\iPhone\Ad-Hoc</OutputPath> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<ConsolePause>False</ConsolePause> | |||||
<MtouchArch>ARMv7, ARM64</MtouchArch> | |||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements> | |||||
<BuildIpa>True</BuildIpa> | |||||
<CodesignProvision>Automatic:AdHoc</CodesignProvision> | |||||
<CodesignKey>iPhone Distribution</CodesignKey> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'AppStore|iPhone' "> | |||||
<DebugType>none</DebugType> | |||||
<Optimize>True</Optimize> | |||||
<OutputPath>bin\iPhone\AppStore</OutputPath> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<ConsolePause>False</ConsolePause> | |||||
<MtouchArch>ARMv7, ARM64</MtouchArch> | |||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements> | |||||
<CodesignProvision>Automatic:AppStore</CodesignProvision> | |||||
<CodesignKey>iPhone Distribution</CodesignKey> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<Compile Include="Main.cs" /> | |||||
<Compile Include="AppDelegate.cs" /> | |||||
<None Include="app.config" /> | |||||
<None Include="Info.plist" /> | |||||
<Compile Include="Properties\AssemblyInfo.cs" /> | |||||
<InterfaceDefinition Include="Resources\LaunchScreen.xib" /> | |||||
<None Include="packages.config" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<Reference Include="System" /> | |||||
<Reference Include="System.Xml" /> | |||||
<Reference Include="System.Core" /> | |||||
<Reference Include="Xamarin.Forms.Core, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\Xamarin.Forms.2.3.3.166-pre4\lib\Xamarin.iOS10\Xamarin.Forms.Core.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Forms.Platform, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\Xamarin.Forms.2.3.3.166-pre4\lib\Xamarin.iOS10\Xamarin.Forms.Platform.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Forms.Platform.iOS, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\Xamarin.Forms.2.3.3.166-pre4\lib\Xamarin.iOS10\Xamarin.Forms.Platform.iOS.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Forms.Xaml, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\Xamarin.Forms.2.3.3.166-pre4\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Xamarin.iOS" /> | |||||
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\xunit.abstractions.2.0.1\lib\netstandard1.0\xunit.abstractions.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="xunit.assert, Version=2.2.0.3444, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\xunit.assert.2.2.0-beta4-build3444\lib\netstandard1.0\xunit.assert.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="xunit.core, Version=2.2.0.3444, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\xunit.extensibility.core.2.2.0-beta4-build3444\lib\netstandard1.0\xunit.core.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="xunit.execution.dotnet, Version=2.2.0.3444, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\xunit.extensibility.execution.2.2.0-beta4-build3444\lib\netstandard1.0\xunit.execution.dotnet.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="xunit.runner.devices, Version=2.1.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\xunit.runner.devices.2.1.0\lib\Xamarin.iOS\xunit.runner.devices.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="xunit.runner.utility.dotnet, Version=2.2.0.3444, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\packages\xunit.runner.utility.2.2.0-beta4-build3444\lib\netstandard1.1\xunit.runner.utility.dotnet.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<Content Include="AppDelegate.cs.txt" /> | |||||
<Content Include="Entitlements.plist" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<ProjectReference Include="..\eShopOnContainers.UnitTests\eShopOnContainers.UnitTests.csproj"> | |||||
<Project>{f7b6a162-bc4d-4924-b16a-713f9b0344e7}</Project> | |||||
<Name>eShopOnContainers.UnitTests</Name> | |||||
</ProjectReference> | |||||
</ItemGroup> | |||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" /> | |||||
<Import Project="..\..\packages\Xamarin.Forms.2.3.3.166-pre4\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets" Condition="Exists('..\..\packages\Xamarin.Forms.2.3.3.166-pre4\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets')" /> | |||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> | |||||
<PropertyGroup> | |||||
<ErrorText>Este proyecto hace referencia a los paquetes NuGet que faltan en este equipo. Use la restauración de paquetes NuGet para descargarlos. Para obtener más información, consulte http://go.microsoft.com/fwlink/?LinkID=322105. El archivo que falta es {0}.</ErrorText> | |||||
</PropertyGroup> | |||||
<Error Condition="!Exists('..\..\packages\Xamarin.Forms.2.3.3.166-pre4\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Xamarin.Forms.2.3.3.166-pre4\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets'))" /> | |||||
<Error Condition="!Exists('..\..\packages\xunit.runner.devices.2.1.0\build\Xamarin.iOS\xunit.runner.devices.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\xunit.runner.devices.2.1.0\build\Xamarin.iOS\xunit.runner.devices.targets'))" /> | |||||
</Target> | |||||
<Import Project="..\..\packages\xunit.runner.devices.2.1.0\build\Xamarin.iOS\xunit.runner.devices.targets" Condition="Exists('..\..\packages\xunit.runner.devices.2.1.0\build\Xamarin.iOS\xunit.runner.devices.targets')" /> | |||||
</Project> |
@ -1,41 +0,0 @@ | |||||
{ | |||||
"version": "0.2.0", | |||||
"configurations": [ | |||||
{ | |||||
"name": ".NET Core Launch (web)", | |||||
"type": "coreclr", | |||||
"request": "launch", | |||||
"preLaunchTask": "build", | |||||
"program": "${workspaceRoot}\\bin\\Debug\\netcoreapp1.0\\Ordering.API.dll", | |||||
"args": [], | |||||
"cwd": "${workspaceRoot}", | |||||
"stopAtEntry": false, | |||||
"launchBrowser": { | |||||
"enabled": true, | |||||
"args": "${auto-detect-url}", | |||||
"windows": { | |||||
"command": "cmd.exe", | |||||
"args": "/C start ${auto-detect-url}" | |||||
}, | |||||
"osx": { | |||||
"command": "open" | |||||
}, | |||||
"linux": { | |||||
"command": "xdg-open" | |||||
} | |||||
}, | |||||
"env": { | |||||
"ASPNETCORE_ENVIRONMENT": "Development" | |||||
}, | |||||
"sourceFileMap": { | |||||
"/Views": "${workspaceRoot}/Views" | |||||
} | |||||
}, | |||||
{ | |||||
"name": ".NET Core Attach", | |||||
"type": "coreclr", | |||||
"request": "attach", | |||||
"processId": "${command.pickProcess}" | |||||
} | |||||
] | |||||
} |
@ -1,16 +0,0 @@ | |||||
{ | |||||
"version": "0.1.0", | |||||
"command": "dotnet", | |||||
"isShellCommand": true, | |||||
"args": [], | |||||
"tasks": [ | |||||
{ | |||||
"taskName": "build", | |||||
"args": [ | |||||
"${workspaceRoot}\\project.json" | |||||
], | |||||
"isBuildCommand": true, | |||||
"problemMatcher": "$msCompile" | |||||
} | |||||
] | |||||
} |
@ -1,23 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.AspNetCore.Mvc; | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers | |||||
{ | |||||
[Route("api/[controller]")] | |||||
public class EnvironmentInfoController : Controller | |||||
{ | |||||
// GET api/environmentInfo/machinename | |||||
[HttpGet("machinename")] | |||||
public dynamic GetMachineName() | |||||
{ | |||||
return new | |||||
{ | |||||
InstanceName = Environment.MachineName | |||||
}; | |||||
} | |||||
} | |||||
} |
@ -1,129 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.AspNetCore.Mvc; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel; | |||||
using Microsoft.EntityFrameworkCore; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Contracts; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.Queries; | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers | |||||
{ | |||||
[Route("api/[controller]")] | |||||
public class OrderingController : Controller | |||||
{ | |||||
private IOrderRepository _orderRepository; | |||||
private IOrderdingQueries _queries; | |||||
//private OrderingDbContext _context; | |||||
public OrderingController(IOrderRepository orderRepository, | |||||
IOrderdingQueries orderingQueries //, | |||||
//OrderingDbContext context | |||||
) | |||||
{ | |||||
//Injected objects from the IoC container | |||||
_orderRepository = orderRepository; | |||||
_queries = orderingQueries; | |||||
//_context = context; | |||||
} | |||||
// GET api/ordering/orders | |||||
[HttpGet("orders")] | |||||
public async Task<IActionResult> GetAllOrders() | |||||
{ | |||||
dynamic response = await _queries.GetAllOrdersIncludingValueObjectsAndChildEntities(); | |||||
return Ok(response); | |||||
} | |||||
// GET api/ordering/orders/xxxGUIDxxxx | |||||
[HttpGet("orders/{orderId:Guid}")] | |||||
public async Task<IActionResult> GetOrderById(Guid orderId) | |||||
{ | |||||
dynamic response = await _queries.GetOrderById(orderId); | |||||
return Ok(response); | |||||
} | |||||
//(CDLTLL) - Using parameters | |||||
//Alternate method if using several parameters instead of part of the URL | |||||
// GET api/ordering/orders/?orderId=xxxGUIDxxx&otherParam=value | |||||
//[HttpGet("orders")] | |||||
//public Order GetOrderByGuid([FromUri] Guid orderId, [FromUri] string otherParam) | |||||
// POST api/ordering/orders/create | |||||
[HttpPut("orders/create")] | |||||
public async Task<IActionResult> Post([FromBody]Order order) | |||||
{ | |||||
_orderRepository.Add(order); | |||||
int numChanges = await _orderRepository.UnitOfWork.CommitAsync(); | |||||
return Ok(numChanges); | |||||
} | |||||
// PUT api/ordering/orders/xxxOrderGUIDxxxx/update | |||||
[HttpPut("orders/{orderId:Guid}/update")] | |||||
public async Task<IActionResult> UpdateOrder(Guid orderID, [FromBody] Order orderToUpdate) | |||||
{ | |||||
_orderRepository.Update(orderToUpdate); | |||||
int numChanges = await _orderRepository.UnitOfWork.CommitAsync(); | |||||
return Ok(numChanges); | |||||
} | |||||
// DELETE api/ordering/orders/xxxOrderGUIDxxxx | |||||
[HttpDelete("orders/{orderId:Guid}/remove")] | |||||
public async Task<IActionResult> Remove(Guid id) | |||||
{ | |||||
await _orderRepository.Remove(id); | |||||
int numChanges = await _orderRepository.UnitOfWork.CommitAsync(); | |||||
return Ok(numChanges); | |||||
} | |||||
// GET api/ordering/orders/add_test_data_and_get_all | |||||
[HttpGet("orders/add_test_data_and_get_all")] | |||||
public async Task<IActionResult> AddTestDataAndGetAllOrders() | |||||
{ | |||||
//TEST ADDING ORDERS ********************************* | |||||
//Create generic Address ValueObject | |||||
Address sampleAddress = new Address("15703 NE 61st Ct.", | |||||
"Redmond", | |||||
"Washington", | |||||
"WA", | |||||
"United States", | |||||
"US", | |||||
"98052", | |||||
47.661492, | |||||
-122.131309 | |||||
); | |||||
//Create sample Orders | |||||
Order order1 = new Order(Guid.NewGuid(), sampleAddress, sampleAddress); | |||||
//Add a few OrderItems | |||||
order1.AddNewOrderItem(Guid.NewGuid(), 2, 25, 30); | |||||
order1.AddNewOrderItem(Guid.NewGuid(), 1, 58, 0); | |||||
order1.AddNewOrderItem(Guid.NewGuid(), 1, 60, 0); | |||||
order1.AddNewOrderItem(Guid.NewGuid(), 3, 12, 0); | |||||
order1.AddNewOrderItem(Guid.NewGuid(), 5, 3, 0); | |||||
_orderRepository.Add(order1); | |||||
int numRecs = await _orderRepository.UnitOfWork.CommitAsync(); | |||||
//_context.Orders.Add(order1); | |||||
//_context.SaveChanges(); | |||||
//***************************************************** | |||||
dynamic response = await _queries.GetAllOrdersIncludingValueObjectsAndChildEntities(); | |||||
return Ok(response); | |||||
} | |||||
} | |||||
} | |||||
@ -0,0 +1,98 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers | |||||
{ | |||||
using Application.Commands; | |||||
using Application.Queries; | |||||
using MediatR; | |||||
using Microsoft.AspNetCore.Mvc; | |||||
using Models; | |||||
using System; | |||||
using System.Threading.Tasks; | |||||
[Route("api/v1/[controller]")] | |||||
public class OrdersController : Controller | |||||
{ | |||||
private readonly IMediator _mediator; | |||||
private readonly IOrderQueries _orderQueries; | |||||
public OrdersController(IMediator mediator, IOrderQueries orderQueries) | |||||
{ | |||||
if (mediator == null) | |||||
{ | |||||
throw new ArgumentNullException(nameof(mediator)); | |||||
} | |||||
if (orderQueries == null) | |||||
{ | |||||
throw new ArgumentNullException(nameof(orderQueries)); | |||||
} | |||||
_mediator = mediator; | |||||
_orderQueries = orderQueries; | |||||
} | |||||
[Route("new")] | |||||
[HttpPost] | |||||
public async Task<IActionResult> AddOrder([FromBody]NewOrderViewModel order) | |||||
{ | |||||
var newOrderRequest = new NewOrderRequest() | |||||
{ | |||||
Buyer =GetUserName(), //TODO | |||||
CardTypeId = 1, //TODO | |||||
CardHolderName = order.CardHolderName, | |||||
CardNumber = order.CardNumber, | |||||
CardExpiration = order.CardExpiration, | |||||
CardSecurityNumber = order.CardSecurityNumber, | |||||
State = order.ShippingState, | |||||
City = order.ShippingCity, | |||||
Country = order.ShippingCountry, | |||||
Street = order.ShippingStreet | |||||
}; | |||||
var added = await _mediator.SendAsync(newOrderRequest); | |||||
if (added) | |||||
{ | |||||
return Ok(); | |||||
} | |||||
return BadRequest(); | |||||
} | |||||
[Route("{orderId:int}")] | |||||
[HttpGet] | |||||
public async Task<IActionResult> GetOrder(int orderId) | |||||
{ | |||||
var order = await _orderQueries.GetOrder(orderId); | |||||
return Ok(order); | |||||
} | |||||
[Route("")] | |||||
[HttpGet] | |||||
public async Task<IActionResult> GetOrders() | |||||
{ | |||||
var orders = await _orderQueries.GetOrders(); | |||||
return Ok(orders); | |||||
} | |||||
[Route("cardtypes")] | |||||
[HttpGet] | |||||
public async Task<IActionResult> GetCardTypes() | |||||
{ | |||||
var cardTypes = await _orderQueries.GetCardTypes(); | |||||
return Ok(cardTypes); | |||||
} | |||||
string GetUserName() | |||||
{ | |||||
return "MOCK"; | |||||
} | |||||
} | |||||
} | |||||
@ -0,0 +1,14 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.ActionResults | |||||
{ | |||||
using AspNetCore.Http; | |||||
using Microsoft.AspNetCore.Mvc; | |||||
public class InternalServerErrorObjectResult : ObjectResult | |||||
{ | |||||
public InternalServerErrorObjectResult(object error) | |||||
: base(error) | |||||
{ | |||||
StatusCode = StatusCodes.Status500InternalServerError; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,28 @@ | |||||
| |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.AutofacModules | |||||
{ | |||||
using Application.Queries; | |||||
using Autofac; | |||||
using Domain.Repositories; | |||||
using Ordering.Infrastructure.Repositories; | |||||
public class ApplicationModule | |||||
:Autofac.Module | |||||
{ | |||||
protected override void Load(ContainerBuilder builder) | |||||
{ | |||||
builder.RegisterType<OrderQueries>() | |||||
.As<IOrderQueries>() | |||||
.InstancePerLifetimeScope(); | |||||
builder.RegisterType<BuyerRepository>() | |||||
.As<IBuyerRepository>() | |||||
.InstancePerLifetimeScope(); | |||||
builder.RegisterType<OrderRepository>() | |||||
.As<IOrderRepository>() | |||||
.InstancePerLifetimeScope(); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,43 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.AutofacModules | |||||
{ | |||||
using Application.Commands; | |||||
using Application.Decorators; | |||||
using Autofac; | |||||
using Autofac.Core; | |||||
using MediatR; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Reflection; | |||||
public class MediatorModule : Autofac.Module | |||||
{ | |||||
protected override void Load(ContainerBuilder builder) | |||||
{ | |||||
builder.RegisterAssemblyTypes(typeof(IMediator).GetTypeInfo().Assembly) | |||||
.AsImplementedInterfaces(); | |||||
builder.RegisterAssemblyTypes(typeof(NewOrderRequest).GetTypeInfo().Assembly) | |||||
.As(o => o.GetInterfaces() | |||||
.Where(i => i.IsClosedTypeOf(typeof(IAsyncRequestHandler<,>))) | |||||
.Select(i => new KeyedService("IAsyncRequestHandler", i))); | |||||
builder.Register<SingleInstanceFactory>(context => | |||||
{ | |||||
var componentContext = context.Resolve<IComponentContext>(); | |||||
return t => componentContext.Resolve(t); | |||||
}); | |||||
builder.Register<MultiInstanceFactory>(context => | |||||
{ | |||||
var componentContext = context.Resolve<IComponentContext>(); | |||||
return t => (IEnumerable<object>)componentContext.Resolve(typeof(IEnumerable<>).MakeGenericType(t)); | |||||
}); | |||||
builder.RegisterGenericDecorator(typeof(LogDecorator<,>), | |||||
typeof(IAsyncRequestHandler<,>), | |||||
"IAsyncRequestHandler"); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,45 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Filters | |||||
{ | |||||
using Microsoft.AspNetCore.Hosting; | |||||
using Microsoft.AspNetCore.Mvc.Filters; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.ActionResults; | |||||
using Microsoft.Extensions.Logging; | |||||
public class HttpGlobalExceptionFilter : IExceptionFilter | |||||
{ | |||||
private readonly IHostingEnvironment env; | |||||
private readonly ILogger<HttpGlobalExceptionFilter> logger; | |||||
public HttpGlobalExceptionFilter(IHostingEnvironment env, ILogger<HttpGlobalExceptionFilter> logger) | |||||
{ | |||||
this.env = env; | |||||
this.logger = logger; | |||||
} | |||||
public void OnException(ExceptionContext context) | |||||
{ | |||||
logger.LogError(new EventId(context.Exception.HResult), | |||||
context.Exception, | |||||
context.Exception.Message); | |||||
var json = new JsonErrorResponse | |||||
{ | |||||
Messages = new[] { "An error ocurr.Try it again." } | |||||
}; | |||||
if (env.IsDevelopment()) | |||||
{ | |||||
json.DeveloperMeesage = context.Exception; | |||||
} | |||||
context.Result = new InternalServerErrorObjectResult(json); | |||||
} | |||||
private class JsonErrorResponse | |||||
{ | |||||
public string[] Messages { get; set; } | |||||
public object DeveloperMeesage { get; set; } | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,227 @@ | |||||
using System; | |||||
using Microsoft.EntityFrameworkCore; | |||||
using Microsoft.EntityFrameworkCore.Infrastructure; | |||||
using Microsoft.EntityFrameworkCore.Metadata; | |||||
using Microsoft.EntityFrameworkCore.Migrations; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; | |||||
namespace Ordering.API.Infrastructure.Migrations | |||||
{ | |||||
[DbContext(typeof(OrderingContext))] | |||||
[Migration("20161124133626_InitialModel")] | |||||
partial class InitialModel | |||||
{ | |||||
protected override void BuildTargetModel(ModelBuilder modelBuilder) | |||||
{ | |||||
modelBuilder | |||||
.HasAnnotation("ProductVersion", "1.0.1") | |||||
.HasAnnotation("SqlServer:Sequence:ordering.buyerseq", "'buyerseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") | |||||
.HasAnnotation("SqlServer:Sequence:ordering.orderseq", "'orderseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") | |||||
.HasAnnotation("SqlServer:Sequence:ordering.paymentseq", "'paymentseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") | |||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Address", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<string>("City"); | |||||
b.Property<string>("Country"); | |||||
b.Property<string>("State"); | |||||
b.Property<string>("Street"); | |||||
b.Property<string>("ZipCode"); | |||||
b.HasKey("Id"); | |||||
b.ToTable("address","ordering"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Buyer", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd() | |||||
.HasAnnotation("SqlServer:HiLoSequenceName", "buyerseq") | |||||
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering") | |||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); | |||||
b.Property<string>("FullName") | |||||
.IsRequired() | |||||
.HasAnnotation("MaxLength", 200); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("FullName") | |||||
.IsUnique(); | |||||
b.ToTable("buyers","ordering"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.CardType", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd() | |||||
.HasDefaultValue(1); | |||||
b.Property<string>("Name") | |||||
.IsRequired() | |||||
.HasAnnotation("MaxLength", 200); | |||||
b.HasKey("Id"); | |||||
b.ToTable("cardtypes","ordering"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Order", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd() | |||||
.HasAnnotation("SqlServer:HiLoSequenceName", "orderseq") | |||||
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering") | |||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); | |||||
b.Property<int>("BuyerId"); | |||||
b.Property<DateTime>("OrderDate"); | |||||
b.Property<int>("PaymentId"); | |||||
b.Property<int?>("ShippingAddressId"); | |||||
b.Property<int>("StatusId"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("BuyerId"); | |||||
b.HasIndex("PaymentId"); | |||||
b.HasIndex("ShippingAddressId"); | |||||
b.HasIndex("StatusId"); | |||||
b.ToTable("orders","ordering"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.OrderItem", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<decimal>("Discount"); | |||||
b.Property<int>("OrderId"); | |||||
b.Property<int>("ProductId"); | |||||
b.Property<string>("ProductName") | |||||
.IsRequired(); | |||||
b.Property<decimal>("UnitPrice"); | |||||
b.Property<int>("Units") | |||||
.ValueGeneratedOnAdd() | |||||
.HasAnnotation("SqlServer:DefaultValue", 1); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("OrderId"); | |||||
b.ToTable("orderItems","ordering"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.OrderStatus", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd() | |||||
.HasDefaultValue(1); | |||||
b.Property<string>("Name") | |||||
.IsRequired() | |||||
.HasAnnotation("MaxLength", 200); | |||||
b.HasKey("Id"); | |||||
b.ToTable("orderstatus","ordering"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Payment", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd() | |||||
.HasAnnotation("SqlServer:HiLoSequenceName", "paymentseq") | |||||
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering") | |||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); | |||||
b.Property<int>("BuyerId"); | |||||
b.Property<string>("CardHolderName") | |||||
.IsRequired() | |||||
.HasAnnotation("MaxLength", 200); | |||||
b.Property<string>("CardNumber") | |||||
.IsRequired() | |||||
.HasAnnotation("MaxLength", 25); | |||||
b.Property<int>("CardTypeId"); | |||||
b.Property<DateTime>("Expiration"); | |||||
b.Property<string>("SecurityNumber"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("BuyerId"); | |||||
b.HasIndex("CardTypeId"); | |||||
b.ToTable("payments","ordering"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Order", b => | |||||
{ | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Buyer", "Buyer") | |||||
.WithMany() | |||||
.HasForeignKey("BuyerId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Payment", "Payment") | |||||
.WithMany() | |||||
.HasForeignKey("PaymentId"); | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Address", "ShippingAddress") | |||||
.WithMany() | |||||
.HasForeignKey("ShippingAddressId"); | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.OrderStatus", "Status") | |||||
.WithMany() | |||||
.HasForeignKey("StatusId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.OrderItem", b => | |||||
{ | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Order") | |||||
.WithMany("OrderItems") | |||||
.HasForeignKey("OrderId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Payment", b => | |||||
{ | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Buyer") | |||||
.WithMany("Payments") | |||||
.HasForeignKey("BuyerId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.CardType", "CardType") | |||||
.WithMany() | |||||
.HasForeignKey("CardTypeId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,283 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using Microsoft.EntityFrameworkCore.Migrations; | |||||
using Microsoft.EntityFrameworkCore.Metadata; | |||||
namespace Ordering.API.Infrastructure.Migrations | |||||
{ | |||||
public partial class InitialModel : Migration | |||||
{ | |||||
protected override void Up(MigrationBuilder migrationBuilder) | |||||
{ | |||||
migrationBuilder.EnsureSchema( | |||||
name: "ordering"); | |||||
migrationBuilder.CreateSequence( | |||||
name: "buyerseq", | |||||
schema: "ordering", | |||||
incrementBy: 10); | |||||
migrationBuilder.CreateSequence( | |||||
name: "orderseq", | |||||
schema: "ordering", | |||||
incrementBy: 10); | |||||
migrationBuilder.CreateSequence( | |||||
name: "paymentseq", | |||||
schema: "ordering", | |||||
incrementBy: 10); | |||||
migrationBuilder.CreateTable( | |||||
name: "address", | |||||
schema: "ordering", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false) | |||||
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), | |||||
City = table.Column<string>(nullable: true), | |||||
Country = table.Column<string>(nullable: true), | |||||
State = table.Column<string>(nullable: true), | |||||
Street = table.Column<string>(nullable: true), | |||||
ZipCode = table.Column<string>(nullable: true) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_address", x => x.Id); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "buyers", | |||||
schema: "ordering", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false), | |||||
FullName = table.Column<string>(maxLength: 200, nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_buyers", x => x.Id); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "cardtypes", | |||||
schema: "ordering", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false, defaultValue: 1), | |||||
Name = table.Column<string>(maxLength: 200, nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_cardtypes", x => x.Id); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "orderstatus", | |||||
schema: "ordering", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false, defaultValue: 1), | |||||
Name = table.Column<string>(maxLength: 200, nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_orderstatus", x => x.Id); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "payments", | |||||
schema: "ordering", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false), | |||||
BuyerId = table.Column<int>(nullable: false), | |||||
CardHolderName = table.Column<string>(maxLength: 200, nullable: false), | |||||
CardNumber = table.Column<string>(maxLength: 25, nullable: false), | |||||
CardTypeId = table.Column<int>(nullable: false), | |||||
Expiration = table.Column<DateTime>(nullable: false), | |||||
SecurityNumber = table.Column<string>(nullable: true) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_payments", x => x.Id); | |||||
table.ForeignKey( | |||||
name: "FK_payments_buyers_BuyerId", | |||||
column: x => x.BuyerId, | |||||
principalSchema: "ordering", | |||||
principalTable: "buyers", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Cascade); | |||||
table.ForeignKey( | |||||
name: "FK_payments_cardtypes_CardTypeId", | |||||
column: x => x.CardTypeId, | |||||
principalSchema: "ordering", | |||||
principalTable: "cardtypes", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Cascade); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "orders", | |||||
schema: "ordering", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false), | |||||
BuyerId = table.Column<int>(nullable: false), | |||||
OrderDate = table.Column<DateTime>(nullable: false), | |||||
PaymentId = table.Column<int>(nullable: false), | |||||
ShippingAddressId = table.Column<int>(nullable: true), | |||||
StatusId = table.Column<int>(nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_orders", x => x.Id); | |||||
table.ForeignKey( | |||||
name: "FK_orders_buyers_BuyerId", | |||||
column: x => x.BuyerId, | |||||
principalSchema: "ordering", | |||||
principalTable: "buyers", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Cascade); | |||||
table.ForeignKey( | |||||
name: "FK_orders_payments_PaymentId", | |||||
column: x => x.PaymentId, | |||||
principalSchema: "ordering", | |||||
principalTable: "payments", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Restrict); | |||||
table.ForeignKey( | |||||
name: "FK_orders_address_ShippingAddressId", | |||||
column: x => x.ShippingAddressId, | |||||
principalSchema: "ordering", | |||||
principalTable: "address", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Restrict); | |||||
table.ForeignKey( | |||||
name: "FK_orders_orderstatus_StatusId", | |||||
column: x => x.StatusId, | |||||
principalSchema: "ordering", | |||||
principalTable: "orderstatus", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Cascade); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "orderItems", | |||||
schema: "ordering", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false) | |||||
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), | |||||
Discount = table.Column<decimal>(nullable: false), | |||||
OrderId = table.Column<int>(nullable: false), | |||||
ProductId = table.Column<int>(nullable: false), | |||||
ProductName = table.Column<string>(nullable: false), | |||||
UnitPrice = table.Column<decimal>(nullable: false), | |||||
Units = table.Column<int>(nullable: false, defaultValue: 1) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_orderItems", x => x.Id); | |||||
table.ForeignKey( | |||||
name: "FK_orderItems_orders_OrderId", | |||||
column: x => x.OrderId, | |||||
principalSchema: "ordering", | |||||
principalTable: "orders", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Cascade); | |||||
}); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_buyers_FullName", | |||||
schema: "ordering", | |||||
table: "buyers", | |||||
column: "FullName", | |||||
unique: true); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_orders_BuyerId", | |||||
schema: "ordering", | |||||
table: "orders", | |||||
column: "BuyerId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_orders_PaymentId", | |||||
schema: "ordering", | |||||
table: "orders", | |||||
column: "PaymentId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_orders_ShippingAddressId", | |||||
schema: "ordering", | |||||
table: "orders", | |||||
column: "ShippingAddressId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_orders_StatusId", | |||||
schema: "ordering", | |||||
table: "orders", | |||||
column: "StatusId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_orderItems_OrderId", | |||||
schema: "ordering", | |||||
table: "orderItems", | |||||
column: "OrderId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_payments_BuyerId", | |||||
schema: "ordering", | |||||
table: "payments", | |||||
column: "BuyerId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_payments_CardTypeId", | |||||
schema: "ordering", | |||||
table: "payments", | |||||
column: "CardTypeId"); | |||||
} | |||||
protected override void Down(MigrationBuilder migrationBuilder) | |||||
{ | |||||
migrationBuilder.DropSequence( | |||||
name: "buyerseq", | |||||
schema: "ordering"); | |||||
migrationBuilder.DropSequence( | |||||
name: "orderseq", | |||||
schema: "ordering"); | |||||
migrationBuilder.DropSequence( | |||||
name: "paymentseq", | |||||
schema: "ordering"); | |||||
migrationBuilder.DropTable( | |||||
name: "orderItems", | |||||
schema: "ordering"); | |||||
migrationBuilder.DropTable( | |||||
name: "orders", | |||||
schema: "ordering"); | |||||
migrationBuilder.DropTable( | |||||
name: "payments", | |||||
schema: "ordering"); | |||||
migrationBuilder.DropTable( | |||||
name: "address", | |||||
schema: "ordering"); | |||||
migrationBuilder.DropTable( | |||||
name: "orderstatus", | |||||
schema: "ordering"); | |||||
migrationBuilder.DropTable( | |||||
name: "buyers", | |||||
schema: "ordering"); | |||||
migrationBuilder.DropTable( | |||||
name: "cardtypes", | |||||
schema: "ordering"); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,226 @@ | |||||
using System; | |||||
using Microsoft.EntityFrameworkCore; | |||||
using Microsoft.EntityFrameworkCore.Infrastructure; | |||||
using Microsoft.EntityFrameworkCore.Metadata; | |||||
using Microsoft.EntityFrameworkCore.Migrations; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; | |||||
namespace Ordering.API.Infrastructure.Migrations | |||||
{ | |||||
[DbContext(typeof(OrderingContext))] | |||||
partial class OrderingContextModelSnapshot : ModelSnapshot | |||||
{ | |||||
protected override void BuildModel(ModelBuilder modelBuilder) | |||||
{ | |||||
modelBuilder | |||||
.HasAnnotation("ProductVersion", "1.0.1") | |||||
.HasAnnotation("SqlServer:Sequence:ordering.buyerseq", "'buyerseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") | |||||
.HasAnnotation("SqlServer:Sequence:ordering.orderseq", "'orderseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") | |||||
.HasAnnotation("SqlServer:Sequence:ordering.paymentseq", "'paymentseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") | |||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Address", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<string>("City"); | |||||
b.Property<string>("Country"); | |||||
b.Property<string>("State"); | |||||
b.Property<string>("Street"); | |||||
b.Property<string>("ZipCode"); | |||||
b.HasKey("Id"); | |||||
b.ToTable("address","ordering"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Buyer", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd() | |||||
.HasAnnotation("SqlServer:HiLoSequenceName", "buyerseq") | |||||
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering") | |||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); | |||||
b.Property<string>("FullName") | |||||
.IsRequired() | |||||
.HasAnnotation("MaxLength", 200); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("FullName") | |||||
.IsUnique(); | |||||
b.ToTable("buyers","ordering"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.CardType", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd() | |||||
.HasDefaultValue(1); | |||||
b.Property<string>("Name") | |||||
.IsRequired() | |||||
.HasAnnotation("MaxLength", 200); | |||||
b.HasKey("Id"); | |||||
b.ToTable("cardtypes","ordering"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Order", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd() | |||||
.HasAnnotation("SqlServer:HiLoSequenceName", "orderseq") | |||||
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering") | |||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); | |||||
b.Property<int>("BuyerId"); | |||||
b.Property<DateTime>("OrderDate"); | |||||
b.Property<int>("PaymentId"); | |||||
b.Property<int?>("ShippingAddressId"); | |||||
b.Property<int>("StatusId"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("BuyerId"); | |||||
b.HasIndex("PaymentId"); | |||||
b.HasIndex("ShippingAddressId"); | |||||
b.HasIndex("StatusId"); | |||||
b.ToTable("orders","ordering"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.OrderItem", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<decimal>("Discount"); | |||||
b.Property<int>("OrderId"); | |||||
b.Property<int>("ProductId"); | |||||
b.Property<string>("ProductName") | |||||
.IsRequired(); | |||||
b.Property<decimal>("UnitPrice"); | |||||
b.Property<int>("Units") | |||||
.ValueGeneratedOnAdd() | |||||
.HasAnnotation("SqlServer:DefaultValue", 1); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("OrderId"); | |||||
b.ToTable("orderItems","ordering"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.OrderStatus", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd() | |||||
.HasDefaultValue(1); | |||||
b.Property<string>("Name") | |||||
.IsRequired() | |||||
.HasAnnotation("MaxLength", 200); | |||||
b.HasKey("Id"); | |||||
b.ToTable("orderstatus","ordering"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Payment", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd() | |||||
.HasAnnotation("SqlServer:HiLoSequenceName", "paymentseq") | |||||
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering") | |||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); | |||||
b.Property<int>("BuyerId"); | |||||
b.Property<string>("CardHolderName") | |||||
.IsRequired() | |||||
.HasAnnotation("MaxLength", 200); | |||||
b.Property<string>("CardNumber") | |||||
.IsRequired() | |||||
.HasAnnotation("MaxLength", 25); | |||||
b.Property<int>("CardTypeId"); | |||||
b.Property<DateTime>("Expiration"); | |||||
b.Property<string>("SecurityNumber"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("BuyerId"); | |||||
b.HasIndex("CardTypeId"); | |||||
b.ToTable("payments","ordering"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Order", b => | |||||
{ | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Buyer", "Buyer") | |||||
.WithMany() | |||||
.HasForeignKey("BuyerId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Payment", "Payment") | |||||
.WithMany() | |||||
.HasForeignKey("PaymentId"); | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Address", "ShippingAddress") | |||||
.WithMany() | |||||
.HasForeignKey("ShippingAddressId"); | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.OrderStatus", "Status") | |||||
.WithMany() | |||||
.HasForeignKey("StatusId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.OrderItem", b => | |||||
{ | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Order") | |||||
.WithMany("OrderItems") | |||||
.HasForeignKey("OrderId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Payment", b => | |||||
{ | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Buyer") | |||||
.WithMany("Payments") | |||||
.HasForeignKey("BuyerId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.CardType", "CardType") | |||||
.WithMany() | |||||
.HasForeignKey("CardTypeId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,42 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure | |||||
{ | |||||
using AspNetCore.Builder; | |||||
using Microsoft.EntityFrameworkCore; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain; | |||||
using Ordering.Infrastructure; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
public class OrderingContextSeed | |||||
{ | |||||
public static async Task SeedAsync(IApplicationBuilder applicationBuilder) | |||||
{ | |||||
var context = (OrderingContext)applicationBuilder | |||||
.ApplicationServices.GetService(typeof(OrderingContext)); | |||||
using (context) | |||||
{ | |||||
context.Database.Migrate(); | |||||
if (!context.CardTypes.Any()) | |||||
{ | |||||
context.CardTypes.Add(CardType.Amex); | |||||
context.CardTypes.Add(CardType.Visa); | |||||
context.CardTypes.Add(CardType.MasterCard); | |||||
await context.SaveChangesAsync(); | |||||
} | |||||
if (!context.OrderStatus.Any()) | |||||
{ | |||||
context.OrderStatus.Add(OrderStatus.Canceled); | |||||
context.OrderStatus.Add(OrderStatus.InProcess); | |||||
context.OrderStatus.Add(OrderStatus.Shipped); | |||||
} | |||||
await context.SaveChangesAsync(); | |||||
} | |||||
} | |||||
} | |||||
} |
@ -1,121 +0,0 @@ | |||||
using System; | |||||
using Microsoft.EntityFrameworkCore; | |||||
using Microsoft.EntityFrameworkCore.Infrastructure; | |||||
using Microsoft.EntityFrameworkCore.Metadata; | |||||
using Microsoft.EntityFrameworkCore.Migrations; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; | |||||
namespace Ordering.API.Migrations | |||||
{ | |||||
[DbContext(typeof(OrderingDbContext))] | |||||
[Migration("20160913204939_Migration1")] | |||||
partial class Migration1 | |||||
{ | |||||
protected override void BuildTargetModel(ModelBuilder modelBuilder) | |||||
{ | |||||
modelBuilder | |||||
.HasAnnotation("ProductVersion", "1.0.0-rtm-21431") | |||||
.HasAnnotation("Relational:Sequence:shared.OrderSequences", "'OrderSequences', 'shared', '1001', '1', '', '', 'Int32', 'False'") | |||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", b => | |||||
{ | |||||
b.Property<Guid>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<string>("City"); | |||||
b.Property<string>("Country"); | |||||
b.Property<string>("CountryCode"); | |||||
b.Property<double>("Latitude"); | |||||
b.Property<double>("Longitude"); | |||||
b.Property<string>("State"); | |||||
b.Property<string>("StateCode"); | |||||
b.Property<string>("Street"); | |||||
b.Property<string>("ZipCode"); | |||||
b.HasKey("Id"); | |||||
b.ToTable("Address"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => | |||||
{ | |||||
b.Property<Guid>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<Guid?>("BillingAddressId"); | |||||
b.Property<Guid>("BuyerId"); | |||||
b.Property<DateTime>("OrderDate"); | |||||
b.Property<int>("SequenceNumber") | |||||
.ValueGeneratedOnAdd() | |||||
.HasDefaultValueSql("NEXT VALUE FOR shared.OrderSequences"); | |||||
b.Property<Guid?>("ShippingAddressId"); | |||||
b.Property<int>("Status"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("BillingAddressId"); | |||||
b.HasIndex("ShippingAddressId"); | |||||
b.ToTable("Orders"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => | |||||
{ | |||||
b.Property<Guid>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<decimal>("Discount"); | |||||
b.Property<int>("FulfillmentRemaining"); | |||||
b.Property<Guid>("OrderId"); | |||||
b.Property<Guid>("ProductId"); | |||||
b.Property<int>("Quantity"); | |||||
b.Property<decimal>("UnitPrice"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("OrderId"); | |||||
b.ToTable("OrderItem"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => | |||||
{ | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "BillingAddress") | |||||
.WithMany() | |||||
.HasForeignKey("BillingAddressId"); | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "ShippingAddress") | |||||
.WithMany() | |||||
.HasForeignKey("ShippingAddressId"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => | |||||
{ | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order") | |||||
.WithMany("OrderItems") | |||||
.HasForeignKey("OrderId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
} | |||||
} | |||||
} |
@ -1,123 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using Microsoft.EntityFrameworkCore.Migrations; | |||||
namespace Ordering.API.Migrations | |||||
{ | |||||
public partial class Migration1 : Migration | |||||
{ | |||||
protected override void Up(MigrationBuilder migrationBuilder) | |||||
{ | |||||
migrationBuilder.EnsureSchema( | |||||
name: "shared"); | |||||
migrationBuilder.CreateSequence<int>( | |||||
name: "OrderSequences", | |||||
schema: "shared", | |||||
startValue: 1001L); | |||||
migrationBuilder.CreateTable( | |||||
name: "Address", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<Guid>(nullable: false), | |||||
City = table.Column<string>(nullable: true), | |||||
Country = table.Column<string>(nullable: true), | |||||
CountryCode = table.Column<string>(nullable: true), | |||||
Latitude = table.Column<double>(nullable: false), | |||||
Longitude = table.Column<double>(nullable: false), | |||||
State = table.Column<string>(nullable: true), | |||||
StateCode = table.Column<string>(nullable: true), | |||||
Street = table.Column<string>(nullable: true), | |||||
ZipCode = table.Column<string>(nullable: true) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_Address", x => x.Id); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "Orders", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<Guid>(nullable: false), | |||||
BillingAddressId = table.Column<Guid>(nullable: true), | |||||
BuyerId = table.Column<Guid>(nullable: false), | |||||
OrderDate = table.Column<DateTime>(nullable: false), | |||||
SequenceNumber = table.Column<int>(nullable: false, defaultValueSql: "NEXT VALUE FOR shared.OrderSequences"), | |||||
ShippingAddressId = table.Column<Guid>(nullable: true), | |||||
Status = table.Column<int>(nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_Orders", x => x.Id); | |||||
table.ForeignKey( | |||||
name: "FK_Orders_Address_BillingAddressId", | |||||
column: x => x.BillingAddressId, | |||||
principalTable: "Address", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Restrict); | |||||
table.ForeignKey( | |||||
name: "FK_Orders_Address_ShippingAddressId", | |||||
column: x => x.ShippingAddressId, | |||||
principalTable: "Address", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Restrict); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "OrderItem", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<Guid>(nullable: false), | |||||
Discount = table.Column<decimal>(nullable: false), | |||||
FulfillmentRemaining = table.Column<int>(nullable: false), | |||||
OrderId = table.Column<Guid>(nullable: false), | |||||
ProductId = table.Column<Guid>(nullable: false), | |||||
Quantity = table.Column<int>(nullable: false), | |||||
UnitPrice = table.Column<decimal>(nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_OrderItem", x => x.Id); | |||||
table.ForeignKey( | |||||
name: "FK_OrderItem_Orders_OrderId", | |||||
column: x => x.OrderId, | |||||
principalTable: "Orders", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Cascade); | |||||
}); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_Orders_BillingAddressId", | |||||
table: "Orders", | |||||
column: "BillingAddressId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_Orders_ShippingAddressId", | |||||
table: "Orders", | |||||
column: "ShippingAddressId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_OrderItem_OrderId", | |||||
table: "OrderItem", | |||||
column: "OrderId"); | |||||
} | |||||
protected override void Down(MigrationBuilder migrationBuilder) | |||||
{ | |||||
migrationBuilder.DropSequence( | |||||
name: "OrderSequences", | |||||
schema: "shared"); | |||||
migrationBuilder.DropTable( | |||||
name: "OrderItem"); | |||||
migrationBuilder.DropTable( | |||||
name: "Orders"); | |||||
migrationBuilder.DropTable( | |||||
name: "Address"); | |||||
} | |||||
} | |||||
} |
@ -1,121 +0,0 @@ | |||||
using System; | |||||
using Microsoft.EntityFrameworkCore; | |||||
using Microsoft.EntityFrameworkCore.Infrastructure; | |||||
using Microsoft.EntityFrameworkCore.Metadata; | |||||
using Microsoft.EntityFrameworkCore.Migrations; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; | |||||
namespace Ordering.API.Migrations | |||||
{ | |||||
[DbContext(typeof(OrderingDbContext))] | |||||
[Migration("20161005002014_Migration_Baseline")] | |||||
partial class Migration_Baseline | |||||
{ | |||||
protected override void BuildTargetModel(ModelBuilder modelBuilder) | |||||
{ | |||||
modelBuilder | |||||
.HasAnnotation("ProductVersion", "1.0.0-rtm-21431") | |||||
.HasAnnotation("Relational:Sequence:shared.OrderSequences", "'OrderSequences', 'shared', '1001', '1', '', '', 'Int32', 'False'") | |||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", b => | |||||
{ | |||||
b.Property<Guid>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<string>("City"); | |||||
b.Property<string>("Country"); | |||||
b.Property<string>("CountryCode"); | |||||
b.Property<double>("Latitude"); | |||||
b.Property<double>("Longitude"); | |||||
b.Property<string>("State"); | |||||
b.Property<string>("StateCode"); | |||||
b.Property<string>("Street"); | |||||
b.Property<string>("ZipCode"); | |||||
b.HasKey("Id"); | |||||
b.ToTable("Address"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => | |||||
{ | |||||
b.Property<Guid>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<Guid?>("BillingAddressId"); | |||||
b.Property<Guid>("BuyerId"); | |||||
b.Property<DateTime>("OrderDate"); | |||||
b.Property<int>("SequenceNumber") | |||||
.ValueGeneratedOnAdd() | |||||
.HasDefaultValueSql("NEXT VALUE FOR shared.OrderSequences"); | |||||
b.Property<Guid?>("ShippingAddressId"); | |||||
b.Property<int>("Status"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("BillingAddressId"); | |||||
b.HasIndex("ShippingAddressId"); | |||||
b.ToTable("Orders"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => | |||||
{ | |||||
b.Property<Guid>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<decimal>("Discount"); | |||||
b.Property<int>("FulfillmentRemaining"); | |||||
b.Property<Guid>("OrderId"); | |||||
b.Property<Guid>("ProductId"); | |||||
b.Property<int>("Quantity"); | |||||
b.Property<decimal>("UnitPrice"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("OrderId"); | |||||
b.ToTable("OrderItem"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => | |||||
{ | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "BillingAddress") | |||||
.WithMany() | |||||
.HasForeignKey("BillingAddressId"); | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "ShippingAddress") | |||||
.WithMany() | |||||
.HasForeignKey("ShippingAddressId"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => | |||||
{ | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order") | |||||
.WithMany("OrderItems") | |||||
.HasForeignKey("OrderId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
} | |||||
} | |||||
} |
@ -1,19 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using Microsoft.EntityFrameworkCore.Migrations; | |||||
namespace Ordering.API.Migrations | |||||
{ | |||||
public partial class Migration_Baseline : Migration | |||||
{ | |||||
protected override void Up(MigrationBuilder migrationBuilder) | |||||
{ | |||||
} | |||||
protected override void Down(MigrationBuilder migrationBuilder) | |||||
{ | |||||
} | |||||
} | |||||
} |
@ -1,121 +0,0 @@ | |||||
using System; | |||||
using Microsoft.EntityFrameworkCore; | |||||
using Microsoft.EntityFrameworkCore.Infrastructure; | |||||
using Microsoft.EntityFrameworkCore.Metadata; | |||||
using Microsoft.EntityFrameworkCore.Migrations; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; | |||||
namespace Ordering.API.Migrations | |||||
{ | |||||
[DbContext(typeof(OrderingDbContext))] | |||||
[Migration("20161005003321_Migration_Cero")] | |||||
partial class Migration_Cero | |||||
{ | |||||
protected override void BuildTargetModel(ModelBuilder modelBuilder) | |||||
{ | |||||
modelBuilder | |||||
.HasAnnotation("ProductVersion", "1.0.0-rtm-21431") | |||||
.HasAnnotation("Relational:Sequence:shared.OrderSequences", "'OrderSequences', 'shared', '1001', '1', '', '', 'Int32', 'False'") | |||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", b => | |||||
{ | |||||
b.Property<Guid>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<string>("City"); | |||||
b.Property<string>("Country"); | |||||
b.Property<string>("CountryCode"); | |||||
b.Property<double>("Latitude"); | |||||
b.Property<double>("Longitude"); | |||||
b.Property<string>("State"); | |||||
b.Property<string>("StateCode"); | |||||
b.Property<string>("Street"); | |||||
b.Property<string>("ZipCode"); | |||||
b.HasKey("Id"); | |||||
b.ToTable("Address"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => | |||||
{ | |||||
b.Property<Guid>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<Guid?>("BillingAddressId"); | |||||
b.Property<Guid>("BuyerId"); | |||||
b.Property<DateTime>("OrderDate"); | |||||
b.Property<int>("SequenceNumber") | |||||
.ValueGeneratedOnAdd() | |||||
.HasDefaultValueSql("NEXT VALUE FOR shared.OrderSequences"); | |||||
b.Property<Guid?>("ShippingAddressId"); | |||||
b.Property<int>("Status"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("BillingAddressId"); | |||||
b.HasIndex("ShippingAddressId"); | |||||
b.ToTable("Orders"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => | |||||
{ | |||||
b.Property<Guid>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<decimal>("Discount"); | |||||
b.Property<int>("FulfillmentRemaining"); | |||||
b.Property<Guid>("OrderId"); | |||||
b.Property<Guid>("ProductId"); | |||||
b.Property<int>("Quantity"); | |||||
b.Property<decimal>("UnitPrice"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("OrderId"); | |||||
b.ToTable("OrderItem"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => | |||||
{ | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "BillingAddress") | |||||
.WithMany() | |||||
.HasForeignKey("BillingAddressId"); | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "ShippingAddress") | |||||
.WithMany() | |||||
.HasForeignKey("ShippingAddressId"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => | |||||
{ | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order") | |||||
.WithMany("OrderItems") | |||||
.HasForeignKey("OrderId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
} | |||||
} | |||||
} |
@ -1,19 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using Microsoft.EntityFrameworkCore.Migrations; | |||||
namespace Ordering.API.Migrations | |||||
{ | |||||
public partial class Migration_Cero : Migration | |||||
{ | |||||
protected override void Up(MigrationBuilder migrationBuilder) | |||||
{ | |||||
} | |||||
protected override void Down(MigrationBuilder migrationBuilder) | |||||
{ | |||||
} | |||||
} | |||||
} |
@ -1,123 +0,0 @@ | |||||
using System; | |||||
using Microsoft.EntityFrameworkCore; | |||||
using Microsoft.EntityFrameworkCore.Infrastructure; | |||||
using Microsoft.EntityFrameworkCore.Metadata; | |||||
using Microsoft.EntityFrameworkCore.Migrations; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; | |||||
namespace Ordering.API.Migrations | |||||
{ | |||||
[DbContext(typeof(OrderingDbContext))] | |||||
[Migration("20161011040943_Migration2")] | |||||
partial class Migration2 | |||||
{ | |||||
protected override void BuildTargetModel(ModelBuilder modelBuilder) | |||||
{ | |||||
modelBuilder | |||||
.HasAnnotation("ProductVersion", "1.0.0-rtm-21431") | |||||
.HasAnnotation("Relational:Sequence:shared.OrderSequences", "'OrderSequences', 'shared', '1001', '1', '', '', 'Int32', 'False'") | |||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", b => | |||||
{ | |||||
b.Property<Guid>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<string>("City"); | |||||
b.Property<string>("Country"); | |||||
b.Property<string>("CountryCode"); | |||||
b.Property<double>("Latitude"); | |||||
b.Property<double>("Longitude"); | |||||
b.Property<string>("State"); | |||||
b.Property<string>("StateCode"); | |||||
b.Property<string>("Street"); | |||||
b.Property<string>("ZipCode"); | |||||
b.HasKey("Id"); | |||||
b.ToTable("Address"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => | |||||
{ | |||||
b.Property<Guid>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<Guid?>("BillingAddressId"); | |||||
b.Property<Guid>("BuyerId"); | |||||
b.Property<DateTime>("OrderDate"); | |||||
b.Property<int>("SequenceNumber") | |||||
.ValueGeneratedOnAdd() | |||||
.HasDefaultValueSql("NEXT VALUE FOR shared.OrderSequences"); | |||||
b.Property<Guid?>("ShippingAddressId"); | |||||
b.Property<int>("Status"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("BillingAddressId"); | |||||
b.HasIndex("ShippingAddressId"); | |||||
b.ToTable("Orders"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => | |||||
{ | |||||
b.Property<Guid>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<decimal>("Discount"); | |||||
b.Property<int>("FulfillmentRemaining"); | |||||
b.Property<Guid>("OrderId"); | |||||
b.Property<Guid>("ProductId"); | |||||
b.Property<string>("ProductName"); | |||||
b.Property<int>("Quantity"); | |||||
b.Property<decimal>("UnitPrice"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("OrderId"); | |||||
b.ToTable("OrderItem"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => | |||||
{ | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "BillingAddress") | |||||
.WithMany() | |||||
.HasForeignKey("BillingAddressId"); | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "ShippingAddress") | |||||
.WithMany() | |||||
.HasForeignKey("ShippingAddressId"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => | |||||
{ | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order") | |||||
.WithMany("OrderItems") | |||||
.HasForeignKey("OrderId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
} | |||||
} | |||||
} |
@ -1,24 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using Microsoft.EntityFrameworkCore.Migrations; | |||||
namespace Ordering.API.Migrations | |||||
{ | |||||
public partial class Migration2 : Migration | |||||
{ | |||||
protected override void Up(MigrationBuilder migrationBuilder) | |||||
{ | |||||
migrationBuilder.AddColumn<string>( | |||||
name: "ProductName", | |||||
table: "OrderItem", | |||||
nullable: true); | |||||
} | |||||
protected override void Down(MigrationBuilder migrationBuilder) | |||||
{ | |||||
migrationBuilder.DropColumn( | |||||
name: "ProductName", | |||||
table: "OrderItem"); | |||||
} | |||||
} | |||||
} |
@ -1,123 +0,0 @@ | |||||
using System; | |||||
using Microsoft.EntityFrameworkCore; | |||||
using Microsoft.EntityFrameworkCore.Infrastructure; | |||||
using Microsoft.EntityFrameworkCore.Metadata; | |||||
using Microsoft.EntityFrameworkCore.Migrations; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; | |||||
namespace Ordering.API.Migrations | |||||
{ | |||||
[DbContext(typeof(OrderingDbContext))] | |||||
[Migration("20161011041130_Migration3")] | |||||
partial class Migration3 | |||||
{ | |||||
protected override void BuildTargetModel(ModelBuilder modelBuilder) | |||||
{ | |||||
modelBuilder | |||||
.HasAnnotation("ProductVersion", "1.0.0-rtm-21431") | |||||
.HasAnnotation("Relational:Sequence:shared.OrderSequences", "'OrderSequences', 'shared', '1001', '1', '', '', 'Int32', 'False'") | |||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", b => | |||||
{ | |||||
b.Property<Guid>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<string>("City"); | |||||
b.Property<string>("Country"); | |||||
b.Property<string>("CountryCode"); | |||||
b.Property<double>("Latitude"); | |||||
b.Property<double>("Longitude"); | |||||
b.Property<string>("State"); | |||||
b.Property<string>("StateCode"); | |||||
b.Property<string>("Street"); | |||||
b.Property<string>("ZipCode"); | |||||
b.HasKey("Id"); | |||||
b.ToTable("Address"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => | |||||
{ | |||||
b.Property<Guid>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<Guid?>("BillingAddressId"); | |||||
b.Property<Guid>("BuyerId"); | |||||
b.Property<DateTime>("OrderDate"); | |||||
b.Property<int>("SequenceNumber") | |||||
.ValueGeneratedOnAdd() | |||||
.HasDefaultValueSql("NEXT VALUE FOR shared.OrderSequences"); | |||||
b.Property<Guid?>("ShippingAddressId"); | |||||
b.Property<int>("Status"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("BillingAddressId"); | |||||
b.HasIndex("ShippingAddressId"); | |||||
b.ToTable("Orders"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => | |||||
{ | |||||
b.Property<Guid>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<decimal>("Discount"); | |||||
b.Property<int>("FulfillmentRemaining"); | |||||
b.Property<Guid>("OrderId"); | |||||
b.Property<Guid>("ProductId"); | |||||
b.Property<string>("ProductName"); | |||||
b.Property<int>("Quantity"); | |||||
b.Property<decimal>("UnitPrice"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("OrderId"); | |||||
b.ToTable("OrderItem"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => | |||||
{ | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "BillingAddress") | |||||
.WithMany() | |||||
.HasForeignKey("BillingAddressId"); | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "ShippingAddress") | |||||
.WithMany() | |||||
.HasForeignKey("ShippingAddressId"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => | |||||
{ | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order") | |||||
.WithMany("OrderItems") | |||||
.HasForeignKey("OrderId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
} | |||||
} | |||||
} |
@ -1,19 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using Microsoft.EntityFrameworkCore.Migrations; | |||||
namespace Ordering.API.Migrations | |||||
{ | |||||
public partial class Migration3 : Migration | |||||
{ | |||||
protected override void Up(MigrationBuilder migrationBuilder) | |||||
{ | |||||
} | |||||
protected override void Down(MigrationBuilder migrationBuilder) | |||||
{ | |||||
} | |||||
} | |||||
} |
@ -1,122 +0,0 @@ | |||||
using System; | |||||
using Microsoft.EntityFrameworkCore; | |||||
using Microsoft.EntityFrameworkCore.Infrastructure; | |||||
using Microsoft.EntityFrameworkCore.Metadata; | |||||
using Microsoft.EntityFrameworkCore.Migrations; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; | |||||
namespace Ordering.API.Migrations | |||||
{ | |||||
[DbContext(typeof(OrderingDbContext))] | |||||
partial class OrderingDbContextModelSnapshot : ModelSnapshot | |||||
{ | |||||
protected override void BuildModel(ModelBuilder modelBuilder) | |||||
{ | |||||
modelBuilder | |||||
.HasAnnotation("ProductVersion", "1.0.0-rtm-21431") | |||||
.HasAnnotation("Relational:Sequence:shared.OrderSequences", "'OrderSequences', 'shared', '1001', '1', '', '', 'Int32', 'False'") | |||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", b => | |||||
{ | |||||
b.Property<Guid>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<string>("City"); | |||||
b.Property<string>("Country"); | |||||
b.Property<string>("CountryCode"); | |||||
b.Property<double>("Latitude"); | |||||
b.Property<double>("Longitude"); | |||||
b.Property<string>("State"); | |||||
b.Property<string>("StateCode"); | |||||
b.Property<string>("Street"); | |||||
b.Property<string>("ZipCode"); | |||||
b.HasKey("Id"); | |||||
b.ToTable("Address"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => | |||||
{ | |||||
b.Property<Guid>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<Guid?>("BillingAddressId"); | |||||
b.Property<Guid>("BuyerId"); | |||||
b.Property<DateTime>("OrderDate"); | |||||
b.Property<int>("SequenceNumber") | |||||
.ValueGeneratedOnAdd() | |||||
.HasDefaultValueSql("NEXT VALUE FOR shared.OrderSequences"); | |||||
b.Property<Guid?>("ShippingAddressId"); | |||||
b.Property<int>("Status"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("BillingAddressId"); | |||||
b.HasIndex("ShippingAddressId"); | |||||
b.ToTable("Orders"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => | |||||
{ | |||||
b.Property<Guid>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<decimal>("Discount"); | |||||
b.Property<int>("FulfillmentRemaining"); | |||||
b.Property<Guid>("OrderId"); | |||||
b.Property<Guid>("ProductId"); | |||||
b.Property<string>("ProductName"); | |||||
b.Property<int>("Quantity"); | |||||
b.Property<decimal>("UnitPrice"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("OrderId"); | |||||
b.ToTable("OrderItem"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => | |||||
{ | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "BillingAddress") | |||||
.WithMany() | |||||
.HasForeignKey("BillingAddressId"); | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "ShippingAddress") | |||||
.WithMany() | |||||
.HasForeignKey("ShippingAddressId"); | |||||
}); | |||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => | |||||
{ | |||||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order") | |||||
.WithMany("OrderItems") | |||||
.HasForeignKey("OrderId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,25 @@ | |||||
using System; | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Models | |||||
{ | |||||
public class NewOrderViewModel | |||||
{ | |||||
public string ShippingCity { get; set; } | |||||
public string ShippingStreet { get; set; } | |||||
public string ShippingState { get; set; } | |||||
public string ShippingCountry { get; set; } | |||||
public string CardType { get; set; } | |||||
public string CardNumber { get; set; } | |||||
public string CardHolderName { get; set; } | |||||
public DateTime CardExpiration { get; set; } | |||||
public string CardSecurityNumber { get; set; } | |||||
} | |||||
} |
@ -1,187 +0,0 @@ | |||||
<!DOCTYPE html> | |||||
<html lang="en"> | |||||
<head> | |||||
<meta charset="utf-8" /> | |||||
<title>Welcome to ASP.NET Core</title> | |||||
<style> | |||||
html { | |||||
background: #f1f1f1; | |||||
height: 100%; | |||||
} | |||||
body { | |||||
background: #fff; | |||||
color: #505050; | |||||
font: 14px 'Segoe UI', tahoma, arial, helvetica, sans-serif; | |||||
margin: 1%; | |||||
min-height: 95.5%; | |||||
border: 1px solid silver; | |||||
position: relative; | |||||
} | |||||
#header { | |||||
padding: 0; | |||||
} | |||||
#header h1 { | |||||
font-size: 44px; | |||||
font-weight: normal; | |||||
margin: 0; | |||||
padding: 10px 30px 10px 30px; | |||||
} | |||||
#header span { | |||||
margin: 0; | |||||
padding: 0 30px; | |||||
display: block; | |||||
} | |||||
#header p { | |||||
font-size: 20px; | |||||
color: #fff; | |||||
background: #007acc; | |||||
padding: 0 30px; | |||||
line-height: 50px; | |||||
margin-top: 25px; | |||||
} | |||||
#header p a { | |||||
color: #fff; | |||||
text-decoration: underline; | |||||
font-weight: bold; | |||||
padding-right: 35px; | |||||
background: no-repeat right bottom url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAWCAMAAAAcqPc3AAAANlBMVEUAAAAAeswfitI9mthXp91us+KCvuaTx+mjz+2x1u+83PLH4vTR5/ba7Pjj8Pns9fv1+v3////wy3dWAAAAAXRSTlMAQObYZgAAAHxJREFUeNp9kVcSwCAIRMHUYoH7XzaxOxJ9P8oyQ1uIqNPwh3s2aLmIM2YtqrLcQIeQEylhuCeUOlhgve5yoBCfWmlnlgkN4H8ykbpaE7gR03AbUHiwoOxUH9Xp+ubd41p1HF3mBPrfC87BHeTdaB3ceeKL9HGpcvX9zu6+DdMWT9KQPvYAAAAASUVORK5CYII=); | |||||
} | |||||
#main { | |||||
padding: 5px 30px; | |||||
clear: both; | |||||
} | |||||
.section { | |||||
width: 21.7%; | |||||
float: left; | |||||
margin: 0 0 0 4%; | |||||
} | |||||
.section h2 { | |||||
font-size: 13px; | |||||
text-transform: uppercase; | |||||
margin: 0; | |||||
border-bottom: 1px solid silver; | |||||
padding-bottom: 12px; | |||||
margin-bottom: 8px; | |||||
} | |||||
.section.first { | |||||
margin-left: 0; | |||||
} | |||||
.section.first h2 { | |||||
font-size: 24px; | |||||
text-transform: none; | |||||
margin-bottom: 25px; | |||||
border: none; | |||||
} | |||||
.section.first li { | |||||
border-top: 1px solid silver; | |||||
padding: 8px 0; | |||||
} | |||||
.section.last { | |||||
margin-right: 0; | |||||
} | |||||
ul { | |||||
list-style: none; | |||||
padding: 0; | |||||
margin: 0; | |||||
line-height: 20px; | |||||
} | |||||
li { | |||||
padding: 4px 0; | |||||
} | |||||
a { | |||||
color: #267cb2; | |||||
text-decoration: none; | |||||
} | |||||
a:hover { | |||||
text-decoration: underline; | |||||
} | |||||
#footer { | |||||
clear: both; | |||||
padding-top: 50px; | |||||
} | |||||
#footer p { | |||||
position: absolute; | |||||
bottom: 10px; | |||||
} | |||||
</style> | |||||
</head> | |||||
<body> | |||||
<div id="header"> | |||||
<h1>Welcome to ASP.NET Core</h1> | |||||
<span> | |||||
We've made some big updates in this release, so it’s <b>important</b> that you spend | |||||
a few minutes to learn what’s new. | |||||
</span> | |||||
<p>You've created a new ASP.NET Core project. <a href="http://go.microsoft.com/fwlink/?LinkId=518016">Learn what's new</a></p> | |||||
</div> | |||||
<div id="main"> | |||||
<div class="section first"> | |||||
<h2>This application consists of:</h2> | |||||
<ul> | |||||
<li>Sample pages using ASP.NET Core MVC</li> | |||||
<li><a href="http://go.microsoft.com/fwlink/?LinkId=518004">Bower</a> for managing client-side libraries</li> | |||||
<li>Theming using <a href="http://go.microsoft.com/fwlink/?LinkID=398939">Bootstrap</a></li> | |||||
</ul> | |||||
</div> | |||||
<div class="section"> | |||||
<h2>How to</h2> | |||||
<ul> | |||||
<li><a href="http://go.microsoft.com/fwlink/?LinkID=398600">Add a Controller and View</a></li> | |||||
<li><a href="http://go.microsoft.com/fwlink/?LinkID=699562">Add an appsetting in config and access it in app.</a></li> | |||||
<li><a href="http://go.microsoft.com/fwlink/?LinkId=699315">Manage User Secrets using Secret Manager.</a></li> | |||||
<li><a href="http://go.microsoft.com/fwlink/?LinkId=699316">Use logging to log a message.</a></li> | |||||
<li><a href="http://go.microsoft.com/fwlink/?LinkId=699317">Add packages using NuGet.</a></li> | |||||
<li><a href="http://go.microsoft.com/fwlink/?LinkId=699318">Add client packages using Bower.</a></li> | |||||
<li><a href="http://go.microsoft.com/fwlink/?LinkId=699319">Target development, staging or production environment.</a></li> | |||||
</ul> | |||||
</div> | |||||
<div class="section"> | |||||
<h2>Overview</h2> | |||||
<ul> | |||||
<li><a href="http://go.microsoft.com/fwlink/?LinkId=518008">Conceptual overview of what is ASP.NET Core</a></li> | |||||
<li><a href="http://go.microsoft.com/fwlink/?LinkId=699320">Fundamentals of ASP.NET Core such as Startup and middleware.</a></li> | |||||
<li><a href="http://go.microsoft.com/fwlink/?LinkId=398602">Working with Data</a></li> | |||||
<li><a href="http://go.microsoft.com/fwlink/?LinkId=398603">Security</a></li> | |||||
<li><a href="http://go.microsoft.com/fwlink/?LinkID=699321">Client side development</a></li> | |||||
<li><a href="http://go.microsoft.com/fwlink/?LinkID=699322">Develop on different platforms</a></li> | |||||
<li><a href="http://go.microsoft.com/fwlink/?LinkID=699323">Read more on the documentation site</a></li> | |||||
</ul> | |||||
</div> | |||||
<div class="section last"> | |||||
<h2>Run & Deploy</h2> | |||||
<ul> | |||||
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517851">Run your app</a></li> | |||||
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517853">Run tools such as EF migrations and more</a></li> | |||||
<li><a href="http://go.microsoft.com/fwlink/?LinkID=398609">Publish to Microsoft Azure Web Apps</a></li> | |||||
</ul> | |||||
</div> | |||||
<div id="footer"> | |||||
<p>We would love to hear your <a href="http://go.microsoft.com/fwlink/?LinkId=518015">feedback</a></p> | |||||
</div> | |||||
</div> | |||||
</body> | |||||
</html> |
@ -1,3 +1,3 @@ | |||||
{ | { | ||||
"ConnectionString": "Server=127.0.0.1;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;" | |||||
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;" | |||||
} | } |
@ -0,0 +1,110 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Commands | |||||
{ | |||||
using Domain.Repositories; | |||||
using MediatR; | |||||
using System.Linq; | |||||
using System; | |||||
using System.Threading.Tasks; | |||||
using Domain; | |||||
public class NewOrderRequestHandler | |||||
: IAsyncRequestHandler<NewOrderRequest, bool> | |||||
{ | |||||
private readonly IBuyerRepository _buyerRepository; | |||||
private readonly IOrderRepository _orderRepository; | |||||
public NewOrderRequestHandler(IBuyerRepository buyerRepository,IOrderRepository orderRepository) | |||||
{ | |||||
if (buyerRepository == null) | |||||
{ | |||||
throw new ArgumentNullException(nameof(buyerRepository)); | |||||
} | |||||
if (orderRepository == null) | |||||
{ | |||||
throw new ArgumentNullException(nameof(orderRepository)); | |||||
} | |||||
_buyerRepository = buyerRepository; | |||||
_orderRepository = orderRepository; | |||||
} | |||||
public async Task<bool> Handle(NewOrderRequest message) | |||||
{ | |||||
//find buyer/payment or add a new one | |||||
var buyer = await _buyerRepository.FindAsync(message.Buyer); | |||||
if (buyer == null) | |||||
{ | |||||
buyer = CreateBuyer(message); | |||||
} | |||||
var payment = GetExistingPaymentOrAddANewOne(buyer, message); | |||||
await _buyerRepository.UnitOfWork.SaveChangesAsync(); | |||||
//create order | |||||
var order = CreateOrder(buyer.Id, payment.Id, 0); | |||||
order.SetAddress( new Address() | |||||
{ | |||||
City = message.City, | |||||
State = message.State, | |||||
Street = message.Street, | |||||
ZipCode = message.ZipCode | |||||
}); | |||||
_orderRepository.Add(order); | |||||
var result = await _orderRepository.UnitOfWork.SaveChangesAsync(); | |||||
return result > 0; | |||||
} | |||||
Payment GetExistingPaymentOrAddANewOne(Buyer buyer, NewOrderRequest message) | |||||
{ | |||||
Payment payment = PaymentAlreadyExist(buyer, message); | |||||
if (payment == null) | |||||
{ | |||||
payment = CreatePayment(message); | |||||
buyer.Payments.Add(payment); | |||||
} | |||||
return payment; | |||||
} | |||||
Payment PaymentAlreadyExist(Domain.Buyer buyer, NewOrderRequest message) | |||||
{ | |||||
return buyer.Payments | |||||
.SingleOrDefault(p => | |||||
{ | |||||
return p.CardHolderName == message.CardHolderName | |||||
&& | |||||
p.CardNumber == message.CardNumber | |||||
&& | |||||
p.Expiration == message.CardExpiration | |||||
&& | |||||
p.SecurityNumber == message.CardSecurityNumber; | |||||
}); | |||||
} | |||||
Buyer CreateBuyer(NewOrderRequest message) | |||||
{ | |||||
return _buyerRepository.Add( | |||||
new Buyer(message.Buyer)); | |||||
} | |||||
Order CreateOrder(int buyerId, int paymentId, int addressId) | |||||
{ | |||||
return new Order(buyerId, paymentId); | |||||
} | |||||
Payment CreatePayment(NewOrderRequest message) | |||||
{ | |||||
return new Payment(message.CardNumber, message.CardSecurityNumber, message.CardHolderName, message.CardExpiration, message.CardTypeId); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,35 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Commands | |||||
{ | |||||
using System; | |||||
using MediatR; | |||||
public class NewOrderRequest | |||||
:IAsyncRequest<bool> | |||||
{ | |||||
public string City { get; set; } | |||||
public string Street { get; set; } | |||||
public string State { get; set; } | |||||
public string Country { get; set; } | |||||
public string ZipCode { get; set; } | |||||
public string CardNumber { get; set; } | |||||
public string CardHolderName { get; set; } | |||||
public DateTime CardExpiration { get; set; } | |||||
public string CardSecurityNumber { get; set; } | |||||
public int CardTypeId { get; set; } | |||||
public string Buyer { get; set; } | |||||
public NewOrderRequest() | |||||
{ | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,34 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Decorators | |||||
{ | |||||
using Extensions.Logging; | |||||
using MediatR; | |||||
using System.Threading.Tasks; | |||||
public class LogDecorator<TRequest, TResponse> | |||||
: IAsyncRequestHandler<TRequest, TResponse> | |||||
where TRequest : IAsyncRequest<TResponse> | |||||
{ | |||||
private readonly IAsyncRequestHandler<TRequest, TResponse> _inner; | |||||
private readonly ILogger<LogDecorator<TRequest, TResponse>> _logger; | |||||
public LogDecorator( | |||||
IAsyncRequestHandler<TRequest, TResponse> inner, | |||||
ILogger<LogDecorator<TRequest, TResponse>> logger) | |||||
{ | |||||
_inner = inner; | |||||
_logger = logger; | |||||
} | |||||
public async Task<TResponse> Handle(TRequest message) | |||||
{ | |||||
_logger.LogInformation($"Executing command {_inner.GetType().FullName}"); | |||||
var response = await _inner.Handle(message); | |||||
_logger.LogInformation($"Succedded executed command {_inner.GetType().FullName}"); | |||||
return response; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,13 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Queries | |||||
{ | |||||
using System.Threading.Tasks; | |||||
public interface IOrderQueries | |||||
{ | |||||
Task<dynamic> GetOrder(int id); | |||||
Task<dynamic> GetOrders(); | |||||
Task<dynamic> GetCardTypes(); | |||||
} | |||||
} |
@ -0,0 +1,55 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Queries | |||||
{ | |||||
using Dapper; | |||||
using Microsoft.Extensions.Configuration; | |||||
using System.Data.SqlClient; | |||||
using System.Threading.Tasks; | |||||
using System; | |||||
public class OrderQueries | |||||
:IOrderQueries | |||||
{ | |||||
private string _connectionString = string.Empty; | |||||
public OrderQueries(IConfiguration configuration) | |||||
{ | |||||
_connectionString = configuration["ConnectionString"]; | |||||
} | |||||
public async Task<dynamic> GetOrder(int id) | |||||
{ | |||||
using (var connection = new SqlConnection(_connectionString)) | |||||
{ | |||||
connection.Open(); | |||||
return await connection.QueryAsync<dynamic>("SELECT * FROM ordering.Orders where Id=@id",new { id }); | |||||
} | |||||
} | |||||
public async Task<dynamic> GetOrders() | |||||
{ | |||||
using (var connection = new SqlConnection(_connectionString)) | |||||
{ | |||||
connection.Open(); | |||||
return await connection.QueryAsync<dynamic>(@"SELECT o.[Id] as ordernumber,o.[OrderDate] as [date],os.[Name] as [status],SUM(oi.units*oi.unitprice) as total | |||||
FROM [ordering].[Orders] o | |||||
LEFT JOIN[ordering].[orderitems] oi ON o.Id = oi.orderid | |||||
LEFT JOIN[ordering].[orderstatus] os on o.StatusId = os.Id | |||||
GROUP BY o.[Id], o.[OrderDate], os.[Name]"); | |||||
} | |||||
} | |||||
public async Task<dynamic> GetCardTypes() | |||||
{ | |||||
using (var connection = new SqlConnection(_connectionString)) | |||||
{ | |||||
connection.Open(); | |||||
return await connection.QueryAsync<dynamic>("SELECT * FROM ordering.cardtypes"); | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,21 @@ | |||||
{ | |||||
"version": "1.0.0-*", | |||||
"dependencies": { | |||||
"NETStandard.Library": "1.6.0", | |||||
"MediatR": "2.1.0", | |||||
"Dapper": "1.50.2", | |||||
"System.Dynamic.Runtime": "4.0.11", | |||||
"Microsoft.CSharp": "4.0.1", | |||||
"Microsoft.Extensions.Configuration": "1.0.0", | |||||
"System.Data.SqlClient": "4.1.0", | |||||
"Microsoft.Extensions.Logging.Abstractions": "1.0.0", | |||||
"Ordering.Domain": "1.0.0-*" | |||||
}, | |||||
"frameworks": { | |||||
"netstandard1.6": { | |||||
"imports": "dnxcore50" | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,20 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain | |||||
{ | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; | |||||
using System; | |||||
public class Address | |||||
: Entity | |||||
{ | |||||
public String Street { get; set; } | |||||
public String City { get; set; } | |||||
public String State { get; set; } | |||||
public String Country { get; set; } | |||||
public String ZipCode { get; set; } | |||||
} | |||||
} |
@ -1,49 +0,0 @@ | |||||
using System; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel | |||||
{ | |||||
public class Buyer : Entity, IAggregateRoot | |||||
{ | |||||
public Buyer(Guid buyerId, string name, string lastName, string email, Address address, string phoneNumber) | |||||
{ | |||||
this.Id = buyerId; | |||||
this.Name = name; | |||||
this.LastName = lastName; | |||||
this.Email = email; | |||||
this.Address = address; | |||||
this.PhoneNumber = phoneNumber; | |||||
} | |||||
public virtual string Name | |||||
{ | |||||
get; | |||||
private set; | |||||
} | |||||
public virtual string LastName | |||||
{ | |||||
get; | |||||
private set; | |||||
} | |||||
public virtual string Email | |||||
{ | |||||
get; | |||||
private set; | |||||
} | |||||
public virtual Address Address | |||||
{ | |||||
get; | |||||
private set; | |||||
} | |||||
public virtual string PhoneNumber | |||||
{ | |||||
get; | |||||
private set; | |||||
} | |||||
} | |||||
} |
@ -1,70 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel | |||||
{ | |||||
public class Address : ValueObject<Address> | |||||
{ | |||||
public Address(string street, | |||||
string city, | |||||
string state, | |||||
string stateCode, | |||||
string country, | |||||
string countryCode, | |||||
string zipCode, | |||||
double latitude = 0, | |||||
double longitude = 0 | |||||
) | |||||
{ | |||||
if (street == null) | |||||
throw new ArgumentNullException("street"); | |||||
if (city == null) | |||||
throw new ArgumentNullException("city"); | |||||
if (state == null) | |||||
throw new ArgumentNullException("state"); | |||||
if (stateCode == null) | |||||
throw new ArgumentNullException("stateCode"); | |||||
if (country == null) | |||||
throw new ArgumentNullException("country"); | |||||
if (countryCode == null) | |||||
throw new ArgumentNullException("countryCode"); | |||||
if (zipCode == null) | |||||
throw new ArgumentNullException("zipCode"); | |||||
//Generate the ID guid - Remove this when EF Core supports ValueObjects | |||||
// https://github.com/aspnet/EntityFramework/issues/246 | |||||
this.Id = Guid.NewGuid(); | |||||
this.Street = street; | |||||
this.City = city; | |||||
this.State = state; | |||||
this.StateCode = stateCode; | |||||
this.Country = country; | |||||
this.CountryCode = countryCode; | |||||
this.ZipCode = zipCode; | |||||
this.Latitude = latitude; | |||||
this.Longitude = longitude; | |||||
} | |||||
//Infrastructure requisite - Parameterless constructor needed by EF | |||||
Address() { } | |||||
public virtual String Street { get; private set; } | |||||
public virtual String City { get; private set; } | |||||
public virtual String State { get; private set; } | |||||
public virtual String StateCode { get; private set; } | |||||
public virtual String Country { get; private set; } | |||||
public virtual String CountryCode { get; private set; } | |||||
public virtual String ZipCode { get; private set; } | |||||
public virtual double Latitude { get; private set; } | |||||
public virtual double Longitude { get; private set; } | |||||
} | |||||
} |
@ -1,112 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel | |||||
{ | |||||
public class Order : Entity, IAggregateRoot | |||||
{ | |||||
public Order(Guid buyerId, Address shippingAddress, Address billingAddress) | |||||
: this(buyerId, shippingAddress, billingAddress, DateTime.UtcNow) | |||||
{ | |||||
} | |||||
public Order(Guid buyerId, Address shippingAddress, Address billingAddress, DateTime orderDate) | |||||
{ | |||||
this.BuyerId = buyerId; | |||||
this.ShippingAddress = shippingAddress; | |||||
this.BillingAddress = billingAddress; | |||||
this.OrderDate = orderDate; | |||||
this.Status = OrderStatus.New; | |||||
} | |||||
//Infrastructure requisite - Parameterless constructor needed by EF | |||||
Order() { } | |||||
//Order ID comes derived from the Entity base class | |||||
List<OrderItem> _orderItems; | |||||
public virtual List<OrderItem> OrderItems | |||||
{ | |||||
get | |||||
{ | |||||
if (_orderItems == null) | |||||
_orderItems = new List<OrderItem>(); | |||||
return _orderItems; | |||||
} | |||||
private set | |||||
{ | |||||
_orderItems = value; | |||||
} | |||||
} | |||||
public string OrderNumber | |||||
{ | |||||
get | |||||
{ | |||||
return string.Format("{0}/{1}-{2}", OrderDate.Year, OrderDate.Month, SequenceNumber); | |||||
} | |||||
} | |||||
public int SequenceNumber { get; set; } | |||||
public virtual Guid BuyerId { get; private set; } | |||||
public virtual Address ShippingAddress { get; private set; } | |||||
public virtual Address BillingAddress { get; private set; } | |||||
public virtual DateTime OrderDate { get; private set; } | |||||
public virtual OrderStatus Status { get; private set; } | |||||
//////////////////////////////////////////////////////////////////////////////////////// | |||||
//Domain Rules and Logic in Order Aggregate-Root (Sample of a "NO ANEMIC DOMAIN MODEL" ) | |||||
//////////////////////////////////////////////////////////////////////////////////////// | |||||
public OrderItem AddNewOrderItem(Guid productId, int quantity, decimal unitPrice, decimal discount) | |||||
{ | |||||
//check preconditions | |||||
if (productId == Guid.Empty) | |||||
throw new ArgumentNullException("productId"); | |||||
if (quantity <= 0) | |||||
{ | |||||
throw new ArgumentException("The quantity of Product in an Order cannot be equal or less than cero"); | |||||
} | |||||
//check discount values | |||||
if (discount < 0) | |||||
discount = 0; | |||||
if (discount > 100) | |||||
discount = 100; | |||||
//create new order line | |||||
var newOrderItem = new OrderItem() | |||||
{ | |||||
OrderId = this.Id, | |||||
ProductId = productId, | |||||
Quantity = quantity, | |||||
FulfillmentRemaining = quantity, | |||||
Discount = discount, | |||||
UnitPrice = unitPrice | |||||
}; | |||||
//set identity | |||||
newOrderItem.GenerateNewIdentity(); | |||||
//add order item | |||||
this.OrderItems.Add(newOrderItem); | |||||
//return added orderline | |||||
return newOrderItem; | |||||
} | |||||
} | |||||
} |
@ -1,33 +0,0 @@ | |||||
using System; | |||||
using System.Runtime.Serialization; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel | |||||
{ | |||||
public class OrderItem : Entity | |||||
{ | |||||
public OrderItem() { } // Infrastructure. EF might need a plain constructor. Do not use. | |||||
//NOTE: The OrderItem Id (Id) comes from the Entity base class | |||||
public Guid ProductId { get; set; } | |||||
public Guid OrderId { get; set; } | |||||
public decimal UnitPrice { get; set; } | |||||
public string ProductName { get; set; } | |||||
public int Quantity { get; set; } | |||||
public decimal Discount { get; set; } | |||||
public int FulfillmentRemaining { get; set; } | |||||
public override string ToString() | |||||
{ | |||||
return String.Format("Product Id: {0}, Quantity: {1}, Fulfillment Remaing: {2}", this.Id, this.Quantity, this.FulfillmentRemaining); | |||||
} | |||||
} | |||||
} |
@ -1,18 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel | |||||
{ | |||||
public enum OrderStatus | |||||
{ | |||||
Unknown, | |||||
New, | |||||
Submitted, | |||||
InProcess, | |||||
Backordered, | |||||
Shipped, | |||||
Canceled, | |||||
} | |||||
} |
@ -0,0 +1,27 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain | |||||
{ | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
public class Buyer | |||||
:Entity,IAggregateRoot | |||||
{ | |||||
public string FullName { get; private set; } | |||||
public HashSet<Payment> Payments { get; private set; } | |||||
protected Buyer() { } | |||||
public Buyer(string fullName) | |||||
{ | |||||
if (String.IsNullOrWhiteSpace(fullName)) | |||||
{ | |||||
throw new ArgumentNullException(nameof(fullName)); | |||||
} | |||||
this.FullName = fullName; | |||||
this.Payments = new HashSet<Payment>(); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,57 @@ | |||||
| |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain | |||||
{ | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
public class CardType | |||||
: Entity | |||||
{ | |||||
public static CardType Amex = new CardType(1, "Amex"); | |||||
public static CardType Visa = new CardType(2, "Visa"); | |||||
public static CardType MasterCard = new CardType(3, "MasterCard"); | |||||
public string Name { get; private set; } | |||||
protected CardType() { } | |||||
public CardType(int id, string name) | |||||
{ | |||||
Id = id; | |||||
Name = name; | |||||
} | |||||
public static IEnumerable<CardType> List() | |||||
{ | |||||
return new[] { Amex, Visa, MasterCard }; | |||||
} | |||||
public static CardType FromName(string name) | |||||
{ | |||||
var state = List() | |||||
.SingleOrDefault(s => String.Equals(s.Name, name, StringComparison.CurrentCultureIgnoreCase)); | |||||
if (state == null) | |||||
{ | |||||
throw new ArgumentException($"Possible values for CardType: {String.Join(",", List().Select(s => s.Name))}"); | |||||
} | |||||
return state; | |||||
} | |||||
public static CardType From(int id) | |||||
{ | |||||
var state = List().SingleOrDefault(s => s.Id == id); | |||||
if (state == null) | |||||
{ | |||||
throw new ArgumentException($"Possible values for CardType: {String.Join(",", List().Select(s => s.Name))}"); | |||||
} | |||||
return state; | |||||
} | |||||
} | |||||
} |
@ -1,15 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Contracts | |||||
{ | |||||
public interface IBuyerRepository : IRepository | |||||
{ | |||||
//TBD - To define Specific Actions Not In Base Repo | |||||
} | |||||
} |
@ -1,20 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Contracts | |||||
{ | |||||
public interface IOrderRepository : IRepository | |||||
{ | |||||
void Add(Order order); | |||||
void Update(Order order); | |||||
Task Remove(Guid id); | |||||
Task<Order> FindAsync(Guid id); | |||||
} | |||||
} | |||||
@ -0,0 +1,50 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain | |||||
{ | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
public class Order | |||||
: Entity, IAggregateRoot | |||||
{ | |||||
public int BuyerId { get; private set; } | |||||
public Buyer Buyer { get; private set; } | |||||
public DateTime OrderDate { get; private set; } | |||||
public int StatusId { get; private set; } | |||||
public OrderStatus Status { get; private set; } | |||||
public ICollection<OrderItem> OrderItems { get; set; } | |||||
public int? ShippingAddressId { get; private set; } | |||||
public Address ShippingAddress { get; private set; } | |||||
public int PaymentId { get; private set; } | |||||
public Payment Payment { get; private set; } | |||||
protected Order() { } | |||||
public Order(int buyerId, int paymentId) | |||||
{ | |||||
BuyerId = buyerId; | |||||
PaymentId = paymentId; | |||||
StatusId = OrderStatus.InProcess.Id; | |||||
OrderDate = DateTime.UtcNow; | |||||
} | |||||
public void SetAddress(Address address) | |||||
{ | |||||
if (address == null) | |||||
{ | |||||
throw new ArgumentNullException(nameof(address)); | |||||
} | |||||
ShippingAddress = address; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,25 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain | |||||
{ | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; | |||||
public class OrderItem | |||||
:Entity | |||||
{ | |||||
public int ProductId { get; private set; } | |||||
public string ProductName { get; private set; } | |||||
public int OrderId { get; private set; } | |||||
public decimal UnitPrice { get; private set; } | |||||
public decimal Discount { get; private set; } | |||||
public int Units { get; private set; } | |||||
protected OrderItem() | |||||
{ | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,57 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain | |||||
{ | |||||
using SeedWork; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
public class OrderStatus | |||||
:Entity | |||||
{ | |||||
public string Name { get; private set; } | |||||
public static OrderStatus InProcess = new OrderStatus(1, nameof(InProcess).ToLowerInvariant()); | |||||
public static OrderStatus Shipped = new OrderStatus(2, nameof(Shipped).ToLowerInvariant()); | |||||
public static OrderStatus Canceled = new OrderStatus(3, nameof(Canceled).ToLowerInvariant()); | |||||
protected OrderStatus() | |||||
{ | |||||
} | |||||
public OrderStatus(int id, string name) | |||||
{ | |||||
Id = id; | |||||
Name = name; | |||||
} | |||||
public static IEnumerable<OrderStatus> List() | |||||
{ | |||||
return new[] { InProcess, Shipped, Canceled }; | |||||
} | |||||
public static OrderStatus FromName(string name) | |||||
{ | |||||
var state = List() | |||||
.SingleOrDefault(s => String.Equals(s.Name, name, StringComparison.CurrentCultureIgnoreCase)); | |||||
if (state == null) | |||||
{ | |||||
throw new ArgumentException($"Possible values for OrderStatus: {String.Join(",", List().Select(s => s.Name))}"); | |||||
} | |||||
return state; | |||||
} | |||||
public static OrderStatus From(int id) | |||||
{ | |||||
var state = List().SingleOrDefault(s => s.Id == id); | |||||
if (state == null) | |||||
{ | |||||
throw new ArgumentException($"Possible values for OrderStatus: {String.Join(",", List().Select(s => s.Name))}"); | |||||
} | |||||
return state; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,55 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain | |||||
{ | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; | |||||
using System; | |||||
public class Payment | |||||
: Entity | |||||
{ | |||||
public int BuyerId { get; private set; } | |||||
public string CardNumber { get; private set; } | |||||
public string SecurityNumber { get; private set; } | |||||
public string CardHolderName { get; private set; } | |||||
public int CardTypeId { get; private set; } | |||||
public CardType CardType { get; private set; } | |||||
public DateTime Expiration { get; private set; } | |||||
protected Payment() { } | |||||
public Payment(string cardNumber, string securityNumber, string cardHolderName, DateTime expiration, int cardTypeId) | |||||
{ | |||||
if (String.IsNullOrWhiteSpace(cardNumber)) | |||||
{ | |||||
throw new ArgumentException(nameof(cardNumber)); | |||||
} | |||||
if (String.IsNullOrWhiteSpace(securityNumber)) | |||||
{ | |||||
throw new ArgumentException(nameof(securityNumber)); | |||||
} | |||||
if (String.IsNullOrWhiteSpace(cardHolderName)) | |||||
{ | |||||
throw new ArgumentException(nameof(cardHolderName)); | |||||
} | |||||
if (expiration < DateTime.UtcNow) | |||||
{ | |||||
throw new ArgumentException(nameof(expiration)); | |||||
} | |||||
this.CardNumber = cardNumber; | |||||
this.SecurityNumber = securityNumber; | |||||
this.CardHolderName = cardHolderName; | |||||
this.Expiration = expiration; | |||||
this.CardTypeId = cardTypeId; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,13 @@ | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Repositories | |||||
{ | |||||
public interface IBuyerRepository | |||||
:IRepository | |||||
{ | |||||
Buyer Add(Buyer buyer); | |||||
Task<Buyer> FindAsync(string name); | |||||
} | |||||
} |
@ -0,0 +1,10 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Repositories | |||||
{ | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; | |||||
public interface IOrderRepository | |||||
:IRepository | |||||
{ | |||||
Order Add(Order order); | |||||
} | |||||
} |
@ -1,10 +1,11 @@ | |||||
using System; | using System; | ||||
using System.Threading; | |||||
using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork | namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork | ||||
{ | { | ||||
public interface IUnitOfWork : IDisposable | public interface IUnitOfWork : IDisposable | ||||
{ | { | ||||
Task<int> CommitAsync(); | |||||
Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken)); | |||||
} | } | ||||
} | } |
@ -1,47 +0,0 @@ | |||||
using System; | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork | |||||
{ | |||||
internal static class IdentityGenerator | |||||
{ | |||||
/// <summary> | |||||
/// This algorithm generates secuential GUIDs across system boundaries, ideal for databases | |||||
/// </summary> | |||||
/// <returns></returns> | |||||
public static Guid NewSequentialGuid() | |||||
{ | |||||
byte[] uid = Guid.NewGuid().ToByteArray(); | |||||
byte[] binDate = BitConverter.GetBytes(DateTime.UtcNow.Ticks); | |||||
byte[] secuentialGuid = new byte[uid.Length]; | |||||
secuentialGuid[0] = uid[0]; | |||||
secuentialGuid[1] = uid[1]; | |||||
secuentialGuid[2] = uid[2]; | |||||
secuentialGuid[3] = uid[3]; | |||||
secuentialGuid[4] = uid[4]; | |||||
secuentialGuid[5] = uid[5]; | |||||
secuentialGuid[6] = uid[6]; | |||||
// set the first part of the 8th byte to '1100' so | |||||
// later we'll be able to validate it was generated by us | |||||
secuentialGuid[7] = (byte)(0xc0 | (0xf & uid[7])); | |||||
// the last 8 bytes are sequential, | |||||
// it minimizes index fragmentation | |||||
// to a degree as long as there are not a large | |||||
// number of Secuential-Guids generated per millisecond | |||||
secuentialGuid[9] = binDate[0]; | |||||
secuentialGuid[8] = binDate[1]; | |||||
secuentialGuid[15] = binDate[2]; | |||||
secuentialGuid[14] = binDate[3]; | |||||
secuentialGuid[13] = binDate[4]; | |||||
secuentialGuid[12] = binDate[5]; | |||||
secuentialGuid[11] = binDate[6]; | |||||
secuentialGuid[10] = binDate[7]; | |||||
return new Guid(secuentialGuid); | |||||
} | |||||
} | |||||
} |
@ -1,150 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using System.Reflection; | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork | |||||
{ | |||||
/// <summary> | |||||
/// Base class for value objects in domain. | |||||
/// Value | |||||
/// </summary> | |||||
/// <typeparam name="TValueObject">The type of this value object</typeparam> | |||||
public class ValueObject<TValueObject> : IEquatable<TValueObject> | |||||
where TValueObject : ValueObject<TValueObject> | |||||
{ | |||||
//A ValueObject doesn't have Identity, but we just need an Id/key so EF knows how to persist | |||||
//becuase in EF Core it still doesn't support ValueObjects or ComplexTypes | |||||
//This should be changed when EF Core supports any of those. | |||||
// https://github.com/aspnet/EntityFramework/issues/246 | |||||
public virtual Guid Id { get; protected set; } | |||||
//IEquatable and Override Equals operators | |||||
/// <summary> | |||||
/// <see cref="M:System.Object.IEquatable{TValueObject}"/> | |||||
/// </summary> | |||||
/// <param name="other"><see cref="M:System.Object.IEquatable{TValueObject}"/></param> | |||||
/// <returns><see cref="M:System.Object.IEquatable{TValueObject}"/></returns> | |||||
public bool Equals(TValueObject other) | |||||
{ | |||||
if ((object)other == null) | |||||
return false; | |||||
if (Object.ReferenceEquals(this, other)) | |||||
return true; | |||||
//compare all public properties | |||||
PropertyInfo[] publicProperties = this.GetType().GetProperties(); | |||||
if ((object)publicProperties != null | |||||
&& | |||||
publicProperties.Any()) | |||||
{ | |||||
return publicProperties.All(p => | |||||
{ | |||||
var left = p.GetValue(this, null); | |||||
var right = p.GetValue(other, null); | |||||
if (typeof(TValueObject).IsAssignableFrom(left.GetType())) | |||||
{ | |||||
//check not self-references... | |||||
return Object.ReferenceEquals(left, right); | |||||
} | |||||
else | |||||
return left.Equals(right); | |||||
}); | |||||
} | |||||
else | |||||
return true; | |||||
} | |||||
/// <summary> | |||||
/// <see cref="M:System.Object.Equals"/> | |||||
/// </summary> | |||||
/// <param name="obj"><see cref="M:System.Object.Equals"/></param> | |||||
/// <returns><see cref="M:System.Object.Equals"/></returns> | |||||
public override bool Equals(object obj) | |||||
{ | |||||
if ((object)obj == null) | |||||
return false; | |||||
if (Object.ReferenceEquals(this, obj)) | |||||
return true; | |||||
ValueObject<TValueObject> item = obj as ValueObject<TValueObject>; | |||||
if ((object)item != null) | |||||
return Equals((TValueObject)item); | |||||
else | |||||
return false; | |||||
} | |||||
/// <summary> | |||||
/// <see cref="M:System.Object.GetHashCode"/> | |||||
/// </summary> | |||||
/// <returns><see cref="M:System.Object.GetHashCode"/></returns> | |||||
public override int GetHashCode() | |||||
{ | |||||
int hashCode = 31; | |||||
bool changeMultiplier = false; | |||||
int index = 1; | |||||
//compare all public properties | |||||
PropertyInfo[] publicProperties = this.GetType().GetProperties(); | |||||
if ((object)publicProperties != null | |||||
&& | |||||
publicProperties.Any()) | |||||
{ | |||||
foreach (var item in publicProperties) | |||||
{ | |||||
object value = item.GetValue(this, null); | |||||
if ((object)value != null) | |||||
{ | |||||
hashCode = hashCode * ((changeMultiplier) ? 59 : 114) + value.GetHashCode(); | |||||
changeMultiplier = !changeMultiplier; | |||||
} | |||||
else | |||||
hashCode = hashCode ^ (index * 13);//only for support {"a",null,null,"a"} <> {null,"a","a",null} | |||||
} | |||||
} | |||||
return hashCode; | |||||
} | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
/// <param name="left"></param> | |||||
/// <param name="right"></param> | |||||
/// <returns></returns> | |||||
public static bool operator ==(ValueObject<TValueObject> left, ValueObject<TValueObject> right) | |||||
{ | |||||
if (Object.Equals(left, null)) | |||||
return (Object.Equals(right, null)) ? true : false; | |||||
else | |||||
return left.Equals(right); | |||||
} | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
/// <param name="left"></param> | |||||
/// <param name="right"></param> | |||||
/// <returns></returns> | |||||
public static bool operator !=(ValueObject<TValueObject> left, ValueObject<TValueObject> right) | |||||
{ | |||||
return !(left == right); | |||||
} | |||||
} | |||||
} | |||||
@ -1,21 +1,19 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||||
<Project ToolsVersion="14.0.25420" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||||
<PropertyGroup> | <PropertyGroup> | ||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25420</VisualStudioVersion> | |||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion> | |||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> | <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" /> | <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" /> | ||||
<PropertyGroup Label="Globals"> | <PropertyGroup Label="Globals"> | ||||
<ProjectGuid>a0afc432-3846-4b4e-bd8e-3c8c896f4967</ProjectGuid> | |||||
<RootNamespace>Ordering.Test</RootNamespace> | |||||
<ProjectGuid>95f1f07c-4d92-4742-bd07-e5b805aab651</ProjectGuid> | |||||
<RootNamespace>Microsoft.eShopOnContainers.Services.Ordering.Infrastructure</RootNamespace> | |||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath> | <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath> | ||||
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath> | <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath> | ||||
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion> | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup> | <PropertyGroup> | ||||
<SchemaVersion>2.0</SchemaVersion> | <SchemaVersion>2.0</SchemaVersion> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | |||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" /> | |||||
</ItemGroup> | |||||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" /> | <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" /> | ||||
</Project> | </Project> |
@ -0,0 +1,180 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure | |||||
{ | |||||
using System; | |||||
using System.Threading.Tasks; | |||||
using Domain.SeedWork; | |||||
using EntityFrameworkCore.Metadata; | |||||
using Microsoft.EntityFrameworkCore; | |||||
using Microsoft.EntityFrameworkCore.Metadata.Builders; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain; | |||||
public class OrderingContext | |||||
: DbContext,IUnitOfWork | |||||
{ | |||||
const string DEFAULT_SCHEMA = "ordering"; | |||||
public DbSet<Order> Orders { get; set; } | |||||
public DbSet<OrderItem> OrderItems { get; set; } | |||||
public DbSet<Payment> Payments { get; set; } | |||||
public DbSet<Buyer> Buyers { get; set; } | |||||
public DbSet<CardType> CardTypes { get; set; } | |||||
public DbSet<OrderStatus> OrderStatus { get; set; } | |||||
public DbSet<Address> Addresses { get; set; } | |||||
public OrderingContext(DbContextOptions options) : base(options) { } | |||||
protected override void OnModelCreating(ModelBuilder modelBuilder) | |||||
{ | |||||
modelBuilder.Entity<Buyer>(ConfigureBuyer); | |||||
modelBuilder.Entity<Payment>(ConfigurePayment); | |||||
modelBuilder.Entity<Order>(ConfigureOrder); | |||||
modelBuilder.Entity<OrderItem>(ConfigureOrderItems); | |||||
modelBuilder.Entity<CardType>(ConfigureCardTypes); | |||||
modelBuilder.Entity<OrderStatus>(ConfigureOrderStatus); | |||||
modelBuilder.Entity<Address>(ConfigureAddress); | |||||
modelBuilder.Entity<Address>() | |||||
.ToTable("address", DEFAULT_SCHEMA); | |||||
} | |||||
void ConfigureBuyer(EntityTypeBuilder<Buyer> buyerConfiguration) | |||||
{ | |||||
buyerConfiguration.ToTable("buyers", DEFAULT_SCHEMA); | |||||
buyerConfiguration.HasIndex(b => b.FullName) | |||||
.IsUnique(true); | |||||
buyerConfiguration.HasKey(b => b.Id); | |||||
buyerConfiguration.Property(b => b.Id) | |||||
.ForSqlServerUseSequenceHiLo("buyerseq", DEFAULT_SCHEMA); | |||||
buyerConfiguration.Property(b => b.FullName) | |||||
.HasMaxLength(200) | |||||
.IsRequired(); | |||||
buyerConfiguration.HasMany(b => b.Payments) | |||||
.WithOne() | |||||
.HasForeignKey(p => p.BuyerId) | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
} | |||||
void ConfigurePayment(EntityTypeBuilder<Payment> paymentConfiguration) | |||||
{ | |||||
paymentConfiguration.ToTable("payments", DEFAULT_SCHEMA); | |||||
paymentConfiguration.HasKey(b => b.Id); | |||||
paymentConfiguration.Property(b => b.Id) | |||||
.ForSqlServerUseSequenceHiLo("paymentseq", DEFAULT_SCHEMA); | |||||
paymentConfiguration.Property(p => p.CardHolderName) | |||||
.HasMaxLength(200) | |||||
.IsRequired(); | |||||
paymentConfiguration.Property(p => p.CardNumber) | |||||
.HasMaxLength(25) | |||||
.IsRequired(); | |||||
paymentConfiguration.Property(p => p.Expiration) | |||||
.IsRequired(); | |||||
paymentConfiguration.HasOne(p => p.CardType) | |||||
.WithMany() | |||||
.HasForeignKey(p => p.CardTypeId); | |||||
} | |||||
void ConfigureOrder(EntityTypeBuilder<Order> orderConfiguration) | |||||
{ | |||||
orderConfiguration.ToTable("orders", DEFAULT_SCHEMA); | |||||
orderConfiguration.HasKey(o => o.Id); | |||||
orderConfiguration.Property(o => o.Id) | |||||
.ForSqlServerUseSequenceHiLo("orderseq", DEFAULT_SCHEMA); | |||||
orderConfiguration.Property(o => o.OrderDate) | |||||
.IsRequired(); | |||||
orderConfiguration.HasOne(o => o.Payment) | |||||
.WithMany() | |||||
.HasForeignKey(o => o.PaymentId) | |||||
.OnDelete(DeleteBehavior.Restrict); | |||||
orderConfiguration.HasOne(o => o.Buyer) | |||||
.WithMany() | |||||
.HasForeignKey(o => o.BuyerId); | |||||
orderConfiguration.HasOne(o => o.Status) | |||||
.WithMany() | |||||
.HasForeignKey(o => o.StatusId); | |||||
} | |||||
void ConfigureOrderItems(EntityTypeBuilder<OrderItem> orderItemConfiguration) | |||||
{ | |||||
orderItemConfiguration.ToTable("orderItems", DEFAULT_SCHEMA); | |||||
orderItemConfiguration.HasKey(o => o.Id); | |||||
orderItemConfiguration.Property(o => o.Discount) | |||||
.IsRequired(); | |||||
orderItemConfiguration.Property(o => o.ProductId) | |||||
.IsRequired(); | |||||
orderItemConfiguration.Property(o => o.ProductName) | |||||
.IsRequired(); | |||||
orderItemConfiguration.Property(o => o.UnitPrice) | |||||
.IsRequired(); | |||||
orderItemConfiguration.Property(o => o.Units) | |||||
.ForSqlServerHasDefaultValue(1) | |||||
.IsRequired(); | |||||
} | |||||
void ConfigureOrderStatus(EntityTypeBuilder<OrderStatus> orderStatusConfiguration) | |||||
{ | |||||
orderStatusConfiguration.ToTable("orderstatus", DEFAULT_SCHEMA); | |||||
orderStatusConfiguration.HasKey(o => o.Id); | |||||
orderStatusConfiguration.Property(o => o.Id) | |||||
.HasDefaultValue(1) | |||||
.IsRequired(); | |||||
orderStatusConfiguration.Property(o => o.Name) | |||||
.HasMaxLength(200) | |||||
.IsRequired(); | |||||
} | |||||
void ConfigureCardTypes(EntityTypeBuilder<CardType> cardTypesConfiguration) | |||||
{ | |||||
cardTypesConfiguration.ToTable("cardtypes", DEFAULT_SCHEMA); | |||||
cardTypesConfiguration.HasKey(ct => ct.Id); | |||||
cardTypesConfiguration.Property(ct => ct.Id) | |||||
.HasDefaultValue(1) | |||||
.IsRequired(); | |||||
cardTypesConfiguration.Property(ct => ct.Name) | |||||
.HasMaxLength(200) | |||||
.IsRequired(); | |||||
} | |||||
void ConfigureAddress(EntityTypeBuilder<Address> addressConfiguration) | |||||
{ | |||||
addressConfiguration.ToTable("address", DEFAULT_SCHEMA); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,19 @@ | |||||
using System.Reflection; | |||||
using System.Runtime.CompilerServices; | |||||
using System.Runtime.InteropServices; | |||||
// General Information about an assembly is controlled through the following | |||||
// set of attributes. Change these attribute values to modify the information | |||||
// associated with an assembly. | |||||
[assembly: AssemblyConfiguration("")] | |||||
[assembly: AssemblyCompany("")] | |||||
[assembly: AssemblyProduct("Ordering.Infrastructure")] | |||||
[assembly: AssemblyTrademark("")] | |||||
// Setting ComVisible to false makes the types in this assembly not visible | |||||
// to COM components. If you need to access a type in this assembly from | |||||
// COM, set the ComVisible attribute to true on that type. | |||||
[assembly: ComVisible(false)] | |||||
// The following GUID is for the ID of the typelib if this project is exposed to COM | |||||
[assembly: Guid("95f1f07c-4d92-4742-bd07-e5b805aab651")] |
@ -0,0 +1,51 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories | |||||
{ | |||||
using Domain.SeedWork; | |||||
using Microsoft.EntityFrameworkCore; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Repositories; | |||||
using System; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
public class BuyerRepository | |||||
: IBuyerRepository | |||||
{ | |||||
private readonly OrderingContext _context; | |||||
public BuyerRepository(OrderingContext context) | |||||
{ | |||||
if (context == null) | |||||
{ | |||||
throw new ArgumentNullException(nameof(context)); | |||||
} | |||||
_context = context; | |||||
} | |||||
public IUnitOfWork UnitOfWork | |||||
{ | |||||
get | |||||
{ | |||||
return _context; | |||||
} | |||||
} | |||||
public Buyer Add(Buyer buyer) | |||||
{ | |||||
return _context.Buyers | |||||
.Add(buyer) | |||||
.Entity; | |||||
} | |||||
public async Task<Buyer> FindAsync(string name) | |||||
{ | |||||
var buyer = await _context.Buyers | |||||
.Include(b => b.Payments) | |||||
.Where(b => b.FullName == name) | |||||
.SingleOrDefaultAsync(); | |||||
return buyer; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,36 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories | |||||
{ | |||||
using Domain; | |||||
using Domain.SeedWork; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Repositories; | |||||
using System; | |||||
public class OrderRepository | |||||
: IOrderRepository | |||||
{ | |||||
private readonly OrderingContext _context; | |||||
public IUnitOfWork UnitOfWork | |||||
{ | |||||
get | |||||
{ | |||||
return _context; | |||||
} | |||||
} | |||||
public OrderRepository(OrderingContext context) | |||||
{ | |||||
if (context == null) | |||||
{ | |||||
throw new ArgumentNullException(nameof(context)); | |||||
} | |||||
_context = context; | |||||
} | |||||
public Order Add(Order order) | |||||
{ | |||||
return _context.Orders.Add(order) | |||||
.Entity; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,16 @@ | |||||
{ | |||||
"version": "1.0.0-*", | |||||
"dependencies": { | |||||
"NETStandard.Library": "1.6.0", | |||||
"Microsoft.EntityFrameworkCore": "1.0.1", | |||||
"Microsoft.EntityFrameworkCore.SqlServer": "1.0.1", | |||||
"Ordering.Domain": "1.0.0-*" | |||||
}, | |||||
"frameworks": { | |||||
"netstandard1.6": { | |||||
"imports": "dnxcore50" | |||||
} | |||||
} | |||||
} |
@ -1,24 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.SqlData.Queries | |||||
{ | |||||
//The OrderingQueries Contracts/Interfaces could be moved to a third assembly | |||||
//We're not putting this contract in the Domain layer assembly because | |||||
//queries/joins are just Application's needs and should not be limited | |||||
//to the Domain Model restrictions (Aggregates and Repositories restrictions). | |||||
// | |||||
//In this case we're using the same EF Context but another good approach | |||||
//is also to simply use SQL sentences for the queries with any Micro-ORM (like Dapper) or even just ADO.NET | |||||
// | |||||
//The point is that Queries are IDEMPOTENT and don't need to commit to DDD Domain restrictions | |||||
//so could be implemented in a completely orthogonal way in regards the Domain Layer (à la CQRS) | |||||
public interface IOrderdingQueries | |||||
{ | |||||
Task<dynamic> GetAllOrdersIncludingValueObjectsAndChildEntities(); | |||||
Task<dynamic> GetOrderById(Guid orderId); | |||||
} | |||||
} |
@ -1,98 +0,0 @@ | |||||
| |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.EntityFrameworkCore; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.Queries; | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.SqlData.Queries | |||||
{ | |||||
//In this case, for the Application queries, we're using the same EF Context but another good approach | |||||
//is also to simply use SQL sentences for the queries with any Micro-ORM (like Dapper) or even just ADO.NET | |||||
// | |||||
//The point is that Queries are IDEMPOTENT and don't need to commit to DDD Domain restrictions | |||||
//so could be implemented in a completely orthogonal way in regards the Domain Layer (à la CQRS) | |||||
public class OrderingQueries : IOrderdingQueries | |||||
{ | |||||
private OrderingDbContext _dbContext; | |||||
public OrderingQueries(OrderingDbContext orderingDbContext) | |||||
{ | |||||
_dbContext = orderingDbContext; | |||||
} | |||||
public async Task<dynamic> GetAllOrdersIncludingValueObjectsAndChildEntities() | |||||
{ | |||||
var orders = await _dbContext.Orders | |||||
.Include(o => o.ShippingAddress) | |||||
.Include(o => o.BillingAddress) | |||||
.Include(o => o.OrderItems) | |||||
.ToListAsync<Order>(); | |||||
// Dynamically generated a Response-Model that includes only the fields you need in the response. | |||||
// This keeps the JSON response minimal. | |||||
// Could also use var | |||||
dynamic response = orders.Select(o => new | |||||
{ | |||||
id = o.Id, | |||||
orderNumber = o.OrderNumber, | |||||
buyerId = o.BuyerId, | |||||
orderDate = o.OrderDate, | |||||
status = o.Status, | |||||
shippingAddress = o.ShippingAddress, | |||||
billingAddress = o.BillingAddress, | |||||
orderItems = o.OrderItems.Select(i => new | |||||
{ | |||||
id = i.Id, | |||||
productId = i.ProductId, | |||||
unitPrice = i.UnitPrice, | |||||
quantity = i.Quantity, | |||||
discount = i.Discount | |||||
} | |||||
) | |||||
}); | |||||
return response; | |||||
} | |||||
public async Task<dynamic> GetOrderById(Guid orderId) | |||||
{ | |||||
var order = await _dbContext.Orders | |||||
.Include(o => o.ShippingAddress) | |||||
.Include(o => o.BillingAddress) | |||||
.Include(o => o.OrderItems) | |||||
.Where(o => o.Id == orderId) | |||||
.SingleOrDefaultAsync<Order>(); | |||||
// Dynamically generated a Response-Model that includes only the fields you need in the response. | |||||
// This keeps the JSON response minimal. | |||||
// Could also use var | |||||
dynamic response = new | |||||
{ | |||||
id = order.Id, | |||||
orderNumber = order.OrderNumber, | |||||
buyerId = order.BuyerId, | |||||
orderDate = order.OrderDate, | |||||
status = order.Status, | |||||
shippingAddress = order.ShippingAddress, | |||||
billingAddress = order.BillingAddress, | |||||
orderItems = order.OrderItems.Select(i => new | |||||
{ | |||||
id = i.Id, | |||||
productId = i.ProductId, | |||||
unitPrice = i.UnitPrice, | |||||
quantity = i.Quantity, | |||||
discount = i.Discount | |||||
} | |||||
) | |||||
}; | |||||
return response; | |||||
} | |||||
} | |||||
} |
@ -1,51 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Contracts; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; | |||||
using Microsoft.EntityFrameworkCore; | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.SqlData.Repositories | |||||
{ | |||||
//1:1 relationship between Repository and Aggregate (i.e. OrderRepository and Order) | |||||
public class OrderRepository : IOrderRepository | |||||
{ | |||||
private readonly OrderingDbContext _context; | |||||
public IUnitOfWork UnitOfWork => _context; | |||||
public OrderRepository(OrderingDbContext orderingDbContext) | |||||
{ | |||||
_context = orderingDbContext; | |||||
} | |||||
public void Add(Order order) | |||||
{ | |||||
_context.Orders.Add(order); | |||||
} | |||||
public void Update(Order order) | |||||
{ | |||||
_context.Orders.Update(order); | |||||
} | |||||
public async Task Remove(Guid orderId) | |||||
{ | |||||
var orderToRemove = await _context.Orders.Where(o => o.Id == orderId).SingleOrDefaultAsync(); | |||||
_context.Orders.Remove(orderToRemove); | |||||
} | |||||
public async Task<Order> FindAsync(Guid id) | |||||
{ | |||||
if (id != Guid.Empty) | |||||
return await _context.Set<Order>().FirstOrDefaultAsync(o => o.Id == id); | |||||
else | |||||
return null; | |||||
} | |||||
} | |||||
} |
@ -1,50 +0,0 @@ | |||||
using Microsoft.EntityFrameworkCore; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork | |||||
{ | |||||
public class DbContextUtil | |||||
{ | |||||
public static DbContextOptions<OrderingDbContext> CreateNewContextOptionsForInMemoryDB() | |||||
{ | |||||
// Create a fresh service provider, and therefore a fresh | |||||
// InMemory database instance. | |||||
var serviceProvider = new ServiceCollection() | |||||
.AddEntityFrameworkInMemoryDatabase() | |||||
.BuildServiceProvider(); | |||||
// Create a new options instance telling the context to use an | |||||
// InMemory database and the new service provider. | |||||
var builder = new DbContextOptionsBuilder<OrderingDbContext>(); | |||||
builder.UseInMemoryDatabase() | |||||
.UseInternalServiceProvider(serviceProvider); | |||||
return builder.Options; | |||||
} | |||||
public static DbContextOptions<OrderingDbContext> CreateNewContextOptionsForSqlDb() | |||||
{ | |||||
// Create a new options instance telling the context to use a Sql database | |||||
var builder = new DbContextOptionsBuilder<OrderingDbContext>(); | |||||
//SQL LocalDB | |||||
//var connString = @"Server=(localdb)\mssqllocaldb;Database=Microsoft.eShopOnContainers.Services.OrderingDb;Trusted_Connection=True;"; | |||||
//SQL SERVER on-premises | |||||
//(Integrated Security) var connString = @"Server=CESARDLBOOKVHD;Database=Microsoft.eShopOnContainers.Services.OrderingDb;Trusted_Connection=True;"; | |||||
//(SQL Server Authentication) | |||||
var connString = @"Server=10.0.75.1;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;"; | |||||
//SQL LOCALDB | |||||
builder.UseSqlServer(connString); | |||||
return builder.Options; | |||||
} | |||||
} | |||||
} |
@ -1,82 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.EntityFrameworkCore; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork | |||||
{ | |||||
public class OrderingDbContext : DbContext, IUnitOfWork | |||||
{ | |||||
public OrderingDbContext(DbContextOptions<OrderingDbContext> options) | |||||
: base(options) | |||||
{ } | |||||
public DbSet<Order> Orders { get; set; } | |||||
//(CDLTLL) | |||||
/* | |||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) | |||||
{ | |||||
//If running from ASP.NET Core, config is done at StartUp.cs --> ConfigureServices() outside | |||||
//and injected through DI later on. The following config is used when running Tests or similar contexts | |||||
if (!optionsBuilder.IsConfigured) | |||||
{ | |||||
//SQL LocalDB | |||||
//var connString = @"Server=(localdb)\mssqllocaldb;Database=Microsoft.eShopOnContainers.Services.OrderingDb;Trusted_Connection=True;"; | |||||
//SQL SERVER on-premises | |||||
//(Integrated Security) | |||||
//var connString = @"Server=CESARDLBOOKVHD;Database=Microsoft.eShopOnContainers.Services.OrderingDb;Trusted_Connection=True;"; | |||||
//(SQL Server Authentication) | |||||
var connString = @"Server=10.0.75.1;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;"; | |||||
//SQL LOCALDB | |||||
optionsBuilder.UseSqlServer(connString); | |||||
} | |||||
} | |||||
*/ | |||||
protected override void OnModelCreating(ModelBuilder modelBuilder) | |||||
{ | |||||
base.OnModelCreating(modelBuilder); | |||||
// Add your customizations after calling base.OnModelCreating(builder); | |||||
//Sequence to be used as part of the OrderNumber | |||||
modelBuilder.HasSequence<int>("OrderSequences", schema: "shared") | |||||
.StartsAt(1001) | |||||
.IncrementsBy(1); | |||||
modelBuilder.Entity<Order>() | |||||
.Property(o => o.SequenceNumber) | |||||
.HasDefaultValueSql("NEXT VALUE FOR shared.OrderSequences"); | |||||
} | |||||
public async Task<int> CommitAsync() | |||||
{ | |||||
int changes = 0; | |||||
try | |||||
{ | |||||
//(CDLTLL) TBD | |||||
//RemoveOrphanedChilds(); | |||||
changes = await base.SaveChangesAsync(); | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
//(CDLTLL) TBD | |||||
//RejectChanges(); | |||||
throw ex; | |||||
} | |||||
return changes; | |||||
} | |||||
} | |||||
} |
@ -1,19 +0,0 @@ | |||||
{ | |||||
"version": "1.0.0-*", | |||||
"dependencies": { | |||||
"Microsoft.EntityFrameworkCore": "1.0.0", | |||||
"Microsoft.EntityFrameworkCore.SqlServer": "1.0.0", | |||||
"NETStandard.Library": "1.6.0", | |||||
"Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.0", | |||||
"Ordering.Domain": "1.0.0-*", | |||||
"Microsoft.EntityFrameworkCore.InMemory": "1.0.0" | |||||
}, | |||||
"frameworks": { | |||||
"netstandard1.6": { | |||||
"imports": [ "dnxcore50", "portable-net451+win8" ] | |||||
} | |||||
} | |||||
} |
@ -1,4 +1,4 @@ | |||||
{ | |||||
{ | |||||
"version": "1.0.0-*", | "version": "1.0.0-*", | ||||
"dependencies": { | "dependencies": { |
@ -1,86 +0,0 @@ | |||||
using System; | |||||
using System.Linq; | |||||
using Xunit; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Contracts; | |||||
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.Repositories; | |||||
using Microsoft.EntityFrameworkCore; | |||||
namespace DataIntegrationTests | |||||
{ | |||||
//Basic documentation for Testing EF Core classes | |||||
// http://ef.readthedocs.io/en/latest/miscellaneous/testing.html | |||||
public class Tests | |||||
{ | |||||
[Fact] | |||||
public async void Add_order_to_data_model() | |||||
{ | |||||
// All contexts that share the same service provider will share the same database | |||||
//Using InMemory DB | |||||
//var options = DbContextUtil.CreateNewContextOptionsForInMemoryDB(); | |||||
//Using Sql Server | |||||
var options = DbContextUtil.CreateNewContextOptionsForSqlDb(); | |||||
// Run the test against one instance of the context | |||||
using (var context = new OrderingDbContext(options)) | |||||
{ | |||||
IOrderRepository orderRepository = new OrderRepository(context); | |||||
//Create generic Address ValueObject | |||||
Address sampleAddress = new Address("15703 NE 61st Ct.", | |||||
"Redmond", | |||||
"Washington", | |||||
"WA", | |||||
"United States", | |||||
"US", | |||||
"98052", | |||||
47.661492, | |||||
-122.131309 | |||||
); | |||||
//Create sample Orders | |||||
Order order1 = new Order(Guid.NewGuid(), sampleAddress, sampleAddress); | |||||
//Add a few OrderItems | |||||
order1.AddNewOrderItem(Guid.NewGuid(), 2, 25, 30); | |||||
order1.AddNewOrderItem(Guid.NewGuid(), 1, 58, 0); | |||||
order1.AddNewOrderItem(Guid.NewGuid(), 1, 60, 0); | |||||
order1.AddNewOrderItem(Guid.NewGuid(), 3, 12, 0); | |||||
order1.AddNewOrderItem(Guid.NewGuid(), 5, 3, 0); | |||||
orderRepository.Add(order1); | |||||
int numChanges = await orderRepository.UnitOfWork.CommitAsync(); | |||||
//With no Async Repository | |||||
//context.Orders.Add(order1); | |||||
//context.SaveChanges(); | |||||
} | |||||
//// Use a separate instance of the context to verify correct data was saved to database | |||||
using (var context = new OrderingDbContext(options)) | |||||
{ | |||||
var orders = context.Orders | |||||
.Include(o => o.ShippingAddress) | |||||
.Include(o => o.BillingAddress) | |||||
.ToList(); | |||||
//Could be using .Load() if you don't want to create a List | |||||
//OTHER SAMPLE | |||||
//var company = context.Companies | |||||
// .Include(co => co.Employees).ThenInclude(emp => emp.Employee_Car) | |||||
// .Include(co => co.Employees).ThenInclude(emp => emp.Employee_Country) | |||||
// .FirstOrDefault(co => co.companyID == companyID); | |||||
//Assert when running test with a clean In-Memory DB | |||||
//Assert.Equal(1, context.Orders.Count()); | |||||
string cityName = orders.First<Order>().ShippingAddress.City; | |||||
Assert.Equal("Redmond", cityName); | |||||
} | |||||
} | |||||
} | |||||
} |
@ -1,30 +0,0 @@ | |||||
{ | |||||
"version": "1.0.0-*", | |||||
"buildOptions": { | |||||
"debugType": "portable" | |||||
}, | |||||
"dependencies": { | |||||
"System.Runtime.Serialization.Primitives": "4.1.1", | |||||
"xunit": "2.1.0", | |||||
"dotnet-test-xunit": "2.2.0-preview2-build1029", | |||||
"Ordering.Domain": "1.0.0-*", | |||||
"Ordering.SqlData": "1.0.0-*", | |||||
"Microsoft.EntityFrameworkCore.SqlServer": "1.0.0", | |||||
"Microsoft.EntityFrameworkCore.InMemory": "1.0.0" | |||||
}, | |||||
"testRunner": "xunit", | |||||
"frameworks": { | |||||
"netcoreapp1.0": { | |||||
"dependencies": { | |||||
"Microsoft.NETCore.App": { | |||||
"type": "platform", | |||||
"version": "1.0.0" | |||||
} | |||||
}, | |||||
"imports": [ | |||||
"dotnet5.4", | |||||
"portable-net451+win8" | |||||
] | |||||
} | |||||
} | |||||
} |