├── .gitignore
├── CommonAssemblyInfo.cs
├── License.txt
├── README.txt
├── SharpArchitecture.MultiTenant.sln
├── app
├── SharpArchitecture-MultiTenant.ApplicationServices
│ ├── CommandHandlers
│ │ ├── ImportCustomersCommandHandler.cs
│ │ └── UploadFileCommandHandler.cs
│ ├── Commands
│ │ ├── ImportCustomersCommand.cs
│ │ ├── ImportCustomersCommandResult.cs
│ │ ├── UploadFileCommand.cs
│ │ └── UploadFileCommandResult.cs
│ ├── DiskFileStore.cs
│ ├── IFileStore.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ └── SharpArchitecture.MultiTenant.ApplicationServices.csproj
├── SharpArchitecture-MultiTenant.Core
│ ├── Customer.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── SharpArchitecture.MultiTenant.Core.csproj
│ ├── Tenant.cs
│ └── Upload.cs
├── SharpArchitecture-MultiTenant.Data
│ ├── NHibernateMaps
│ │ ├── AutoPersistenceModelGenerator.cs
│ │ ├── AutomappingConfiguration.cs
│ │ ├── Conventions
│ │ │ ├── ForeignKeyConvention.cs
│ │ │ ├── HasManyConvention.cs
│ │ │ ├── HasManyToManyConvention.cs
│ │ │ ├── ManyToManyTableNameConvention.cs
│ │ │ ├── PrimaryKeyConvention.cs
│ │ │ ├── ReferenceConvention.cs
│ │ │ └── TableNameConvention.cs
│ │ ├── MultiTenantAutoPersistenceModelGenerator.cs
│ │ └── MultiTenantAutomappingConfiguration.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ └── SharpArchitecture.MultiTenant.Data.csproj
├── SharpArchitecture-MultiTenant.Framework
│ ├── Contracts
│ │ ├── IMultiTenantEntity.cs
│ │ ├── IMultiTenantQuery.cs
│ │ └── IMultiTenantRepository.cs
│ ├── Extensions
│ │ └── TypeExtensions.cs
│ ├── NHibernate
│ │ └── MultiTenantSessionFactoryKeyProvider.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Services
│ │ └── ITenantContext.cs
│ └── SharpArchitecture.MultiTenant.Framework.csproj
├── SharpArchitecture-MultiTenant.Web.Controllers
│ ├── ControllerEnums.cs
│ ├── Customers
│ │ ├── CustomersController.cs
│ │ ├── Queries
│ │ │ ├── ICustomerListQuery.cs
│ │ │ └── Impl
│ │ │ │ └── CustomerListQuery.cs
│ │ └── ViewModels
│ │ │ ├── CustomerFormViewModel.cs
│ │ │ ├── CustomerListViewModel.cs
│ │ │ ├── CustomerViewModel.cs
│ │ │ └── ImportCustomersFormViewModel.cs
│ ├── HomeController.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── RouteRegistrar.cs
│ ├── SharpArchitecture.MultiTenant.Web.Controllers.csproj
│ ├── TempDataExtensions.cs
│ └── Tenants
│ │ ├── Queries
│ │ ├── ITenantListQuery.cs
│ │ └── Impl
│ │ │ └── TenantListQuery.cs
│ │ ├── TenantsController.cs
│ │ └── ViewModels
│ │ ├── TenantFormViewModel.cs
│ │ ├── TenantListViewModel.cs
│ │ └── TenantViewModel.cs
└── SharpArchitecture-MultiTenant.Web
│ ├── App_Data
│ └── dummy.txt
│ ├── CastleWindsor
│ └── ComponentRegistrar.cs
│ ├── Content
│ ├── Images
│ │ ├── cancel.png
│ │ ├── sharp_arch.jpg
│ │ └── sharp_arch_small.gif
│ └── Site.css
│ ├── Controllers
│ ├── ControllerEnums.cs
│ ├── Customers
│ │ ├── CustomersController.cs
│ │ ├── Queries
│ │ │ ├── ICustomerListQuery.cs
│ │ │ └── Impl
│ │ │ │ └── CustomerListQuery.cs
│ │ └── ViewModels
│ │ │ ├── CustomerFormViewModel.cs
│ │ │ ├── CustomerListViewModel.cs
│ │ │ ├── CustomerViewModel.cs
│ │ │ └── ImportCustomersFormViewModel.cs
│ ├── HomeController.cs
│ ├── RouteRegistrar.cs
│ └── Tenants
│ │ ├── Queries
│ │ ├── ITenantListQuery.cs
│ │ └── Impl
│ │ │ └── TenantListQuery.cs
│ │ ├── TenantsController.cs
│ │ └── ViewModels
│ │ ├── TenantFormViewModel.cs
│ │ ├── TenantListViewModel.cs
│ │ └── TenantViewModel.cs
│ ├── Default.aspx
│ ├── Default.aspx.cs
│ ├── Global.asax
│ ├── Global.asax.cs
│ ├── NHibernate.config
│ ├── NHibernate.tenant.config
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── Scripts
│ ├── expressInstall.swf
│ ├── jquery-1.4.2.js
│ ├── jquery-1.4.2.min.js
│ ├── jquery.uploadify.v2.1.4.js
│ ├── jquery.uploadify.v2.1.4.min.js
│ ├── swfobject.js
│ ├── uploadify.allglyphs.swf
│ ├── uploadify.fla
│ └── uploadify.swf
│ ├── Services
│ └── TenantContext.cs
│ ├── SharpArchitecture.MultiTenant.Web.csproj
│ ├── TempDataExtensions.cs
│ ├── Views
│ ├── Customers
│ │ ├── Create.aspx
│ │ ├── Delete.aspx
│ │ ├── Edit.aspx
│ │ ├── Import.aspx
│ │ └── Index.aspx
│ ├── Home
│ │ └── Index.aspx
│ ├── Shared
│ │ ├── DebugFormSubmission.ascx
│ │ ├── Error.aspx
│ │ └── Site.Master
│ ├── Tenants
│ │ ├── Create.aspx
│ │ ├── Delete.aspx
│ │ ├── Edit.aspx
│ │ └── Index.aspx
│ └── Web.config
│ └── Web.config
├── db
└── schema
│ └── UnitTestGeneratedSchema.sql
├── lib
├── Antlr3.Runtime.dll
├── Castle.Core.dll
├── Castle.Services.Logging.Log4netIntegration.dll
├── Castle.Services.Transaction.dll
├── Castle.Windsor.dll
├── CommonServiceLocator.WindsorAdapter.dll
├── FluentNHibernate.dll
├── Gallio.dll
├── Iesi.Collections.dll
├── Inflector.Net.dll
├── MbUnit.dll
├── Microsoft.Practices.ServiceLocation.dll
├── Microsoft.Web.Mvc.dll
├── MvcContrib.FluentHtml.dll
├── MvcContrib.TestHelper.dll
├── MvcContrib.dll
├── NHibernate.ByteCode.Castle.dll
├── NHibernate.Validator.dll
├── NHibernate.dll
├── Newtonsoft.Json.dll
├── Remotion.Data.Linq.dll
├── Rhino.Mocks.dll
├── SharpArch.Domain.dll
├── SharpArch.NHibernate.dll
├── SharpArch.Testing.NUnit.dll
├── SharpArch.Testing.dll
├── SharpArch.Tests.dll
├── SharpArch.Wcf.dll
├── SharpArch.Web.Mvc.dll
├── System.Data.SQLite.DLL
├── System.Web.Abstractions.dll
├── System.Web.Mvc.dll
├── System.Web.Routing.dll
├── log4net.dll
└── nunit.framework.dll
├── logs
├── SharpArch.VSharpArchTemplate.log
└── SharpArchitecture-MultiTenant.Web.log
├── tests
└── SharpArchitecture-MultiTenant.Tests
│ ├── App.config
│ ├── Hibernate.cfg.xml
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── ServiceLocatorInitializer.cs
│ ├── SharpArchitecture.MultiTenant.Data
│ ├── NHibernateMaps
│ │ └── MappingIntegrationTests.cs
│ └── TestDoubles
│ │ └── EntityDuplicateCheckerStub.cs
│ ├── SharpArchitecture.MultiTenant.Framework
│ └── NHibernate
│ │ └── MultiTenantSessionFactoryKeyProviderTests.cs
│ ├── SharpArchitecture.MultiTenant.Tests.csproj
│ └── SharpArchitecture.MultiTenant.Web
│ └── Controllers
│ └── RouteRegistrarTests.cs
└── tools
├── CrudScaffolding
├── CrudScaffolding.csproj
├── EntityScaffoldingDetails.tt
├── Properties
│ └── AssemblyInfo.cs
├── ScaffoldingGeneratorCommand.tt
├── ScaffoldingGeneratorCommand.txt
└── Templates
│ ├── BaseTemplate.tt
│ ├── Core
│ └── DomainObjectTemplate.tt
│ ├── ScaffoldingGenerator.tt
│ ├── Tests
│ ├── Core
│ │ └── DomainObjectTestsTemplate.tt
│ └── Web
│ │ └── Controllers
│ │ └── ControllerTestsTemplate.tt
│ └── Web
│ ├── Controllers
│ ├── AreaRegistrationTemplate.tt
│ └── ControllerTemplate.tt
│ └── Views
│ ├── CreateTemplate.tt
│ ├── DomainObjectFormTemplate.tt
│ ├── EditTemplate.tt
│ ├── IndexTemplate.tt
│ └── ShowTemplate.tt
├── CrudScaffoldingForEnterpriseApp
├── CrudScaffoldingForEnterpriseApp.csproj
├── EntityScaffoldingDetails.tt
├── Properties
│ └── AssemblyInfo.cs
├── ScaffoldingGeneratorCommand.tt
├── ScaffoldingGeneratorCommand.txt
└── Templates
│ ├── ApplicationServices
│ ├── DomainObjectManagementServiceTemplate.tt
│ ├── IDomainObjectManagementServiceTemplate.tt
│ └── ViewModels
│ │ └── DomainObjectFormViewModel.tt
│ ├── BaseTemplate.tt
│ ├── Core
│ ├── ActionConfirmationTemplate.tt
│ ├── DomainObjectTemplate.tt
│ ├── QueryDtos
│ │ └── DomainObjectDtoTemplate.tt
│ └── RepositoryInterfaces
│ │ └── IDomainObjectRepositoryTemplate.tt
│ ├── Data
│ ├── NamedQueries
│ │ └── GetDomainObjectSummariesHbmTemplate.tt
│ └── Repositories
│ │ └── DomainObjectRepositoryTemplate.tt
│ ├── ScaffoldingGenerator.tt
│ ├── Tests
│ ├── ApplicationServices
│ │ └── DomainObjectMgmtServiceTestsTemplate.tt
│ ├── Core
│ │ ├── DomainObjectInstanceFactoryTemplate.tt
│ │ └── DomainObjectTestsTemplate.tt
│ └── Web
│ │ └── Controllers
│ │ └── ControllerTestsTemplate.tt
│ └── Web
│ ├── Controllers
│ ├── AreaRegistrationTemplate.tt
│ └── ControllerTemplate.tt
│ └── Views
│ ├── CreateTemplate.tt
│ ├── DomainObjectFormTemplate.tt
│ ├── EditTemplate.tt
│ ├── IndexTemplate.tt
│ └── ShowTemplate.tt
└── lib
├── MvcContrib.TestHelper.dll
├── MvcContrib.TestHelper.xml
├── Rhino.Mocks.dll
├── Rhino.Mocks.xml
├── SharpArch.dll
├── System.Data.SQLite.DLL
├── nunit.framework.dll
└── nunit.framework.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | #ignore outputs of project
2 | build*/
3 | #src/SharpArch/CommonAssemblyInfo.cs
4 | #ignore thumbnails created by windows
5 | Thumbs.db
6 | #Ignore files build by Visual Studio
7 | *.obj
8 | *.exe
9 | *.pdb
10 | *.user
11 | *.aps
12 | *.pch
13 | *.vspscc
14 | *_i.c
15 | *_p.c
16 | *.ncb
17 | *.suo
18 | *.tlb
19 | *.tlh
20 | *.bak
21 | *.cache
22 | *.ilk
23 | *.log
24 | [Bb]in
25 | [Dd]ebug*/
26 | *.lib
27 | *.sbr
28 | obj/
29 | [Rr]elease*/
30 | _ReSharper*/
31 | [Tt]est[Rr]esult*
32 | #Ignore MonoDevelop files
33 | *.pidb
34 | *.userprefs
35 | *.DS_Store
--------------------------------------------------------------------------------
/CommonAssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | [assembly: AssemblyCompany("Your Company")]
5 | [assembly: AssemblyCopyright("Copyright � Your Company 2009")]
6 | [assembly: AssemblyConfiguration("debug")]
7 | [assembly: AssemblyTrademark("")]
8 | [assembly: AssemblyCulture("")]
9 |
10 | // Setting ComVisible to false makes the types in this assembly not visible
11 | // to COM components. If you need to access a type in this assembly from
12 | // COM, set the ComVisible attribute to true on that type.
13 | [assembly: ComVisible(false)]
14 |
15 | // Version information for an assembly consists of the following four values:
16 | //
17 | // Major Version
18 | // Minor Version
19 | // Build Number
20 | // Revision
21 | //
22 | // You can specify all the values or you can default the Build and Revision Numbers
23 | // by using the '*' as shown below:
24 | // [assembly: AssemblyVersion("1.0.*")]
25 | [assembly: AssemblyVersion("1.0.0.0")]
26 | [assembly: AssemblyFileVersion("1.0.0.0")]
27 | [assembly: AssemblyInformationalVersion("1.0.0.0")]
28 |
--------------------------------------------------------------------------------
/License.txt:
--------------------------------------------------------------------------------
1 | New BSD License for S#arp Architecture Multi Tenant from Yellow Feather Ltd
2 |
3 | Copyright (c) 2010, Yellow Feather Ltd
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without modification,
7 | are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice,
10 | this list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | * Neither the name of Yellow Feather Ltd, nor the names of its
17 | contributors may be used to endorse or promote products derived from this
18 | software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
24 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/README.txt:
--------------------------------------------------------------------------------
1 | S#arp Architecture multi-tenant sample application
2 | ==================================================
3 |
4 | About
5 | =====
6 |
7 | Sample application illustrating a way of implementing a multi-tenant web application on S#arp Architecture.
8 |
9 | The sample uses a seperate database for each tenant and a master database to persist the details of each tenant.
10 | The connection string for each tenant database is selected based on the subdomain.
11 |
12 |
13 | The sample uses the following:
14 |
15 | - Visual Studio 2010
16 | - S#arp Architecture v1.9
17 |
--------------------------------------------------------------------------------
/SharpArchitecture.MultiTenant.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpArchitecture.MultiTenant.Core", "app\SharpArchitecture-MultiTenant.Core\SharpArchitecture.MultiTenant.Core.csproj", "{7696B4F6-2A10-40C4-A1E2-B9768182588C}"
5 | EndProject
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpArchitecture.MultiTenant.ApplicationServices", "app\SharpArchitecture-MultiTenant.ApplicationServices\SharpArchitecture.MultiTenant.ApplicationServices.csproj", "{EA00777D-3D7A-4406-8BFB-E5A90CF0E8A9}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpArchitecture.MultiTenant.Data", "app\SharpArchitecture-MultiTenant.Data\SharpArchitecture.MultiTenant.Data.csproj", "{63E9AECE-3385-44F0-BDF9-4C01DD3C0647}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpArchitecture.MultiTenant.Tests", "tests\SharpArchitecture-MultiTenant.Tests\SharpArchitecture.MultiTenant.Tests.csproj", "{A909BF90-3A0F-4CB9-9D78-44328589BF2C}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpArchitecture.MultiTenant.Web", "app\SharpArchitecture-MultiTenant.Web\SharpArchitecture.MultiTenant.Web.csproj", "{CD10C59F-658A-4297-9E52-A431B2E32EE0}"
13 | EndProject
14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpArchitecture.MultiTenant.Framework", "app\SharpArchitecture-MultiTenant.Framework\SharpArchitecture.MultiTenant.Framework.csproj", "{F5A0D972-5870-4EB8-8400-F7F2435AE11C}"
15 | EndProject
16 | Global
17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
18 | Debug|Any CPU = Debug|Any CPU
19 | Release|Any CPU = Release|Any CPU
20 | EndGlobalSection
21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
22 | {7696B4F6-2A10-40C4-A1E2-B9768182588C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {7696B4F6-2A10-40C4-A1E2-B9768182588C}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {7696B4F6-2A10-40C4-A1E2-B9768182588C}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {7696B4F6-2A10-40C4-A1E2-B9768182588C}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {EA00777D-3D7A-4406-8BFB-E5A90CF0E8A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {EA00777D-3D7A-4406-8BFB-E5A90CF0E8A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {EA00777D-3D7A-4406-8BFB-E5A90CF0E8A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {EA00777D-3D7A-4406-8BFB-E5A90CF0E8A9}.Release|Any CPU.Build.0 = Release|Any CPU
30 | {63E9AECE-3385-44F0-BDF9-4C01DD3C0647}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31 | {63E9AECE-3385-44F0-BDF9-4C01DD3C0647}.Debug|Any CPU.Build.0 = Debug|Any CPU
32 | {63E9AECE-3385-44F0-BDF9-4C01DD3C0647}.Release|Any CPU.ActiveCfg = Release|Any CPU
33 | {63E9AECE-3385-44F0-BDF9-4C01DD3C0647}.Release|Any CPU.Build.0 = Release|Any CPU
34 | {A909BF90-3A0F-4CB9-9D78-44328589BF2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
35 | {A909BF90-3A0F-4CB9-9D78-44328589BF2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
36 | {A909BF90-3A0F-4CB9-9D78-44328589BF2C}.Release|Any CPU.ActiveCfg = Release|Any CPU
37 | {A909BF90-3A0F-4CB9-9D78-44328589BF2C}.Release|Any CPU.Build.0 = Release|Any CPU
38 | {CD10C59F-658A-4297-9E52-A431B2E32EE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39 | {CD10C59F-658A-4297-9E52-A431B2E32EE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
40 | {CD10C59F-658A-4297-9E52-A431B2E32EE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
41 | {CD10C59F-658A-4297-9E52-A431B2E32EE0}.Release|Any CPU.Build.0 = Release|Any CPU
42 | {F5A0D972-5870-4EB8-8400-F7F2435AE11C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
43 | {F5A0D972-5870-4EB8-8400-F7F2435AE11C}.Debug|Any CPU.Build.0 = Debug|Any CPU
44 | {F5A0D972-5870-4EB8-8400-F7F2435AE11C}.Release|Any CPU.ActiveCfg = Release|Any CPU
45 | {F5A0D972-5870-4EB8-8400-F7F2435AE11C}.Release|Any CPU.Build.0 = Release|Any CPU
46 | EndGlobalSection
47 | GlobalSection(SolutionProperties) = preSolution
48 | HideSolutionNode = FALSE
49 | EndGlobalSection
50 | EndGlobal
51 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.ApplicationServices/CommandHandlers/ImportCustomersCommandHandler.cs:
--------------------------------------------------------------------------------
1 | using SharpArch.Domain.Commands;
2 | using SharpArch.Domain.PersistenceSupport;
3 | using SharpArchitecture.MultiTenant.ApplicationServices.Commands;
4 | using SharpArchitecture.MultiTenant.Core;
5 |
6 | namespace SharpArchitecture.MultiTenant.ApplicationServices.CommandHandlers
7 | {
8 | public class ImportCustomersCommandHandler : ICommandHandler
9 | {
10 | private readonly IRepository _customerRepository;
11 |
12 | public ImportCustomersCommandHandler(IRepository customerRepository)
13 | {
14 | _customerRepository = customerRepository;
15 | }
16 |
17 | public ICommandResult Handle(ImportCustomersCommand command)
18 | {
19 | // get uploaded files by command.UploadKey
20 |
21 | // foreach uploaded file
22 | // import file
23 |
24 | _customerRepository.SaveOrUpdate(new Customer { Code = "ABC", Name = "ABC" });
25 | _customerRepository.SaveOrUpdate(new Customer { Code = "DEF", Name = "DEF" });
26 | _customerRepository.SaveOrUpdate(new Customer { Code = "XYZ", Name = "XYZ" });
27 |
28 | return new ImportCustomersCommandResult(true);
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.ApplicationServices/CommandHandlers/UploadFileCommandHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SharpArch.Domain.Commands;
3 | using SharpArch.Domain.PersistenceSupport;
4 | using SharpArchitecture.MultiTenant.ApplicationServices.Commands;
5 | using SharpArchitecture.MultiTenant.Core;
6 |
7 | namespace SharpArchitecture.MultiTenant.ApplicationServices.CommandHandlers
8 | {
9 | public class UploadFileCommandHandler : ICommandHandler
10 | {
11 | private readonly IFileStore _fileStore;
12 | private readonly IRepository _uploadRepository;
13 |
14 | public UploadFileCommandHandler(IFileStore fileStore, IRepository uploadRepository)
15 | {
16 | _fileStore = fileStore;
17 | _uploadRepository = uploadRepository;
18 | }
19 |
20 | public ICommandResult Handle(UploadFileCommand command)
21 | {
22 | try {
23 | var upload = new Upload(command.FileData.FileName, command.GroupId, command.Username);
24 | upload.UploadedPath = _fileStore.SaveUploadedFile(upload.UploadedFilename, command.FileData);
25 | _uploadRepository.SaveOrUpdate(upload);
26 |
27 | return new UploadFileCommandResult(true);
28 | }
29 | catch (Exception ex) {
30 | return new UploadFileCommandResult(false) { Message = "A problem was encountered uploading the file: " + ex.Message };
31 | }
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.ApplicationServices/Commands/ImportCustomersCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel.DataAnnotations;
3 | using SharpArch.Domain.Commands;
4 |
5 | namespace SharpArchitecture.MultiTenant.ApplicationServices.Commands
6 | {
7 | public class ImportCustomersCommand : CommandBase
8 | {
9 | public ImportCustomersCommand(Guid uploadKey)
10 | {
11 | UploadKey = uploadKey;
12 | }
13 |
14 | [Required]
15 | public Guid UploadKey { get; private set; }
16 | }
17 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.ApplicationServices/Commands/ImportCustomersCommandResult.cs:
--------------------------------------------------------------------------------
1 | using SharpArch.Domain.Commands;
2 |
3 | namespace SharpArchitecture.MultiTenant.ApplicationServices.Commands
4 | {
5 | public class ImportCustomersCommandResult : CommandResult
6 | {
7 | public ImportCustomersCommandResult(bool success)
8 | : base(success) {}
9 | }
10 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.ApplicationServices/Commands/UploadFileCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel.DataAnnotations;
3 | using System.Web;
4 | using SharpArch.Domain.Commands;
5 |
6 | namespace SharpArchitecture.MultiTenant.ApplicationServices.Commands
7 | {
8 | public class UploadFileCommand : CommandBase
9 | {
10 | public UploadFileCommand(Guid groupId, HttpPostedFileBase fileData, string username)
11 | {
12 | GroupId = groupId;
13 | FileData = fileData;
14 | Username = username;
15 | }
16 |
17 | [Required]
18 | public Guid GroupId { get; set; }
19 |
20 | [Required]
21 | public HttpPostedFileBase FileData { get; set; }
22 |
23 | [Required]
24 | public string Username { get; set; }
25 | }
26 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.ApplicationServices/Commands/UploadFileCommandResult.cs:
--------------------------------------------------------------------------------
1 | using SharpArch.Domain.Commands;
2 |
3 | namespace SharpArchitecture.MultiTenant.ApplicationServices.Commands
4 | {
5 | public class UploadFileCommandResult : CommandResult
6 | {
7 | public UploadFileCommandResult(bool success)
8 | : base(success) {}
9 |
10 | public string Message { get; set; }
11 | }
12 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.ApplicationServices/DiskFileStore.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Web;
3 | using System.Web.Hosting;
4 |
5 | namespace SharpArchitecture.MultiTenant.ApplicationServices
6 | {
7 | public class DiskFileStore : IFileStore
8 | {
9 | private readonly string _uploadsFolder = HostingEnvironment.MapPath("~/App_Data");
10 |
11 | public string SaveUploadedFile(string destinationFileName, HttpPostedFileBase fileBase)
12 | {
13 | var path = Path.Combine(_uploadsFolder, destinationFileName);
14 | fileBase.SaveAs(path);
15 | return path;
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.ApplicationServices/IFileStore.cs:
--------------------------------------------------------------------------------
1 | using System.Web;
2 |
3 | namespace SharpArchitecture.MultiTenant.ApplicationServices
4 | {
5 | public interface IFileStore
6 | {
7 | string SaveUploadedFile(string destinationFileName, HttpPostedFileBase file);
8 | }
9 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.ApplicationServices/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("SharpArchitecture.MultiTenant.ApplicationServices")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyProduct("SharpArchitecture.MultiTenant.ApplicationServices")]
11 |
12 | // The following GUID is for the ID of the typelib if this project is exposed to COM
13 | [assembly: Guid("1ae6ea39-bf42-4a4f-ba2f-af252f71a9bc")]
14 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.ApplicationServices/SharpArchitecture.MultiTenant.ApplicationServices.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 |
7 |
8 | 2.0
9 | {EA00777D-3D7A-4406-8BFB-E5A90CF0E8A9}
10 | Library
11 | Properties
12 | SharpArchitecture.MultiTenant.ApplicationServices
13 | SharpArchitecture.MultiTenant.ApplicationServices
14 | v4.0
15 | 512
16 |
17 |
18 |
19 | true
20 | full
21 | false
22 | bin\Debug\
23 | DEBUG;TRACE
24 | prompt
25 | 4
26 |
27 |
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 | ..\..\lib\SharpArch.Domain.dll
38 |
39 |
40 |
41 |
42 | 3.5
43 |
44 |
45 |
46 | 3.5
47 |
48 |
49 | 3.5
50 |
51 |
52 |
53 |
54 |
55 |
56 | Properties\CommonAssemblyInfo.cs
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | {7696B4F6-2A10-40C4-A1E2-B9768182588C}
71 | SharpArchitecture-MultiTenant.Core
72 |
73 |
74 | {F5A0D972-5870-4EB8-8400-F7F2435AE11C}
75 | SharpArchitecture.MultiTenant.Framework
76 |
77 |
78 |
79 |
86 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Core/Customer.cs:
--------------------------------------------------------------------------------
1 | using NHibernate.Validator.Constraints;
2 | using SharpArch.Domain.DomainModel;
3 | using SharpArchitecture.MultiTenant.Framework.Contracts;
4 |
5 | namespace SharpArchitecture.MultiTenant.Core
6 | {
7 | public class Customer : Entity, IMultiTenantEntity
8 | {
9 | [DomainSignature]
10 | [NotNullNotEmpty]
11 | public virtual string Code { get; set; }
12 |
13 | [DomainSignature]
14 | [NotNullNotEmpty]
15 | public virtual string Name { get; set; }
16 | }
17 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Core/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("SharpArchitecture.MultiTenant.Core")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyProduct("SharpArchitecture.MultiTenant.Core")]
11 |
12 | // The following GUID is for the ID of the typelib if this project is exposed to COM
13 | [assembly: Guid("9bd5f514-9ec7-4046-bf66-09fa77a067a1")]
14 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Core/SharpArchitecture.MultiTenant.Core.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 |
7 |
8 | 2.0
9 | {7696B4F6-2A10-40C4-A1E2-B9768182588C}
10 | Library
11 | Properties
12 | SharpArchitecture.MultiTenant.Core
13 | SharpArchitecture.MultiTenant.Core
14 | v4.0
15 | 512
16 |
17 |
18 |
19 | true
20 | full
21 | false
22 | bin\Debug\
23 | DEBUG;TRACE
24 | prompt
25 | 4
26 |
27 |
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 | False
38 | ..\..\lib\Microsoft.Practices.ServiceLocation.dll
39 |
40 |
41 |
42 | False
43 | ..\..\lib\Newtonsoft.Json.dll
44 |
45 |
46 | ..\..\lib\NHibernate.Validator.dll
47 |
48 |
49 | ..\..\lib\SharpArch.Domain.dll
50 |
51 |
52 |
53 | 3.5
54 |
55 |
56 |
57 | 3.5
58 |
59 |
60 |
61 |
62 |
63 | Properties\CommonAssemblyInfo.cs
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | {F5A0D972-5870-4EB8-8400-F7F2435AE11C}
73 | SharpArchitecture.MultiTenant.Framework
74 |
75 |
76 |
77 |
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Core/Tenant.cs:
--------------------------------------------------------------------------------
1 | using SharpArch.Domain.DomainModel;
2 |
3 | namespace SharpArchitecture.MultiTenant.Core
4 | {
5 | public class Tenant : Entity
6 | {
7 | public virtual string Name { get; set; }
8 |
9 | [DomainSignature]
10 | public virtual string Domain { get; set; }
11 |
12 | public virtual string ConnectionString { get; set; }
13 | }
14 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Core/Upload.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using NHibernate.Validator.Constraints;
3 | using SharpArch.Domain.DomainModel;
4 | using SharpArchitecture.MultiTenant.Framework.Contracts;
5 |
6 | namespace SharpArchitecture.MultiTenant.Core
7 | {
8 | ///
9 | ///
10 | ///
11 | public class Upload : Entity, IMultiTenantEntity
12 | {
13 | // required by ORM
14 | protected Upload() { }
15 |
16 | ///
17 | /// Initializes a new instance of the class.
18 | ///
19 | /// The filename.
20 | /// The uploaded by.
21 | public Upload(string filename, string uploadedBy)
22 | : this(filename, null, uploadedBy) { }
23 |
24 | ///
25 | /// Initializes a new instance of the class.
26 | ///
27 | /// The filename.
28 | /// The group id.
29 | /// The uploaded by.
30 | public Upload(string filename, Guid? groupId, string uploadedBy)
31 | {
32 | UploadedFilename = Guid.NewGuid().ToString();
33 | Filename = filename;
34 | GroupId = groupId;
35 | UploadedBy = uploadedBy;
36 | UploadedAt = DateTime.Now;
37 | }
38 |
39 | ///
40 | /// Gets or sets the name of the uploaded file.
41 | ///
42 | /// The uploaded filename.
43 | [DomainSignature]
44 | [NotNull]
45 | public virtual string UploadedFilename { get; private set; }
46 |
47 | ///
48 | /// Gets or sets the path to the uploaded file.
49 | ///
50 | /// The uploaded path.
51 | [DomainSignature]
52 | [NotNull]
53 | public virtual string UploadedPath { get; set; }
54 |
55 | ///
56 | /// Gets or sets the filename.
57 | ///
58 | /// The filename.
59 | [NotNullNotEmpty]
60 | public virtual string Filename { get; private set; }
61 |
62 | ///
63 | /// Gets or sets the group id.
64 | /// Optional group id to allow grouping of a number of uploads.
65 | ///
66 | /// The group id.
67 | public virtual Guid? GroupId { get; private set; }
68 |
69 | ///
70 | /// Gets or sets the user who uploaded the file.
71 | ///
72 | /// The uploaded by.
73 | [NotNull]
74 | public virtual string UploadedBy { get; private set; }
75 |
76 | ///
77 | /// Gets or sets the timestamp the file was uploaded.
78 | ///
79 | /// The timestamp the file was uploaded.
80 | [NotNull]
81 | public virtual DateTime UploadedAt { get; private set; }
82 | }
83 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Data/NHibernateMaps/AutoPersistenceModelGenerator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FluentNHibernate.Automapping;
3 | using FluentNHibernate.Conventions;
4 | using SharpArch.Domain.DomainModel;
5 | using SharpArch.NHibernate.FluentNHibernate;
6 | using SharpArchitecture.MultiTenant.Core;
7 | using SharpArchitecture.MultiTenant.Data.NHibernateMaps.Conventions;
8 | using ForeignKeyConvention = SharpArchitecture.MultiTenant.Data.NHibernateMaps.Conventions.ForeignKeyConvention;
9 | using ManyToManyTableNameConvention = SharpArchitecture.MultiTenant.Data.NHibernateMaps.Conventions.ManyToManyTableNameConvention;
10 |
11 | namespace SharpArchitecture.MultiTenant.Data.NHibernateMaps
12 | {
13 | public class AutoPersistenceModelGenerator : IAutoPersistenceModelGenerator
14 | {
15 | #region IAutoPersistenceModelGenerator Members
16 |
17 | public AutoPersistenceModel Generate()
18 | {
19 | return AutoMap.AssemblyOf(GetAutomappingConfiguration())
20 | .Conventions.Setup(GetConventions())
21 | .IgnoreBase()
22 | .IgnoreBase(typeof (EntityWithTypedId<>))
23 | .UseOverridesFromAssemblyOf();
24 | }
25 |
26 | #endregion
27 |
28 | protected virtual IAutomappingConfiguration GetAutomappingConfiguration()
29 | {
30 | return new AutomappingConfiguration();
31 | }
32 |
33 | private Action GetConventions()
34 | {
35 | return c =>
36 | {
37 | c.Add();
38 | c.Add();
39 | c.Add();
40 | c.Add();
41 | c.Add();
42 | c.Add();
43 | c.Add();
44 | };
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Data/NHibernateMaps/AutomappingConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using FluentNHibernate;
4 | using FluentNHibernate.Automapping;
5 | using SharpArch.Domain.DomainModel;
6 | using SharpArchitecture.MultiTenant.Framework.Contracts;
7 | using SharpArchitecture.MultiTenant.Framework.Extensions;
8 |
9 | namespace SharpArchitecture.MultiTenant.Data.NHibernateMaps
10 | {
11 | ///
12 | ///
13 | ///
14 | public class AutomappingConfiguration : DefaultAutomappingConfiguration
15 | {
16 | public override bool ShouldMap(Type type)
17 | {
18 | var isMultiTenantEntity = IsMultiTenantEntity(type);
19 | return type.GetInterfaces().Any(x =>
20 | x.IsGenericType && x.GetGenericTypeDefinition() == typeof (IEntityWithTypedId<>) &&
21 | !isMultiTenantEntity);
22 | }
23 |
24 | public override bool ShouldMap(Member member)
25 | {
26 | return base.ShouldMap(member) && member.CanWrite;
27 | }
28 |
29 | public override bool AbstractClassIsLayerSupertype(Type type)
30 | {
31 | return type == typeof (EntityWithTypedId<>) || type == typeof (Entity);
32 | }
33 |
34 | public override bool IsId(Member member)
35 | {
36 | return member.Name == "Id";
37 | }
38 |
39 | public bool IsMultiTenantEntity(Type type)
40 | {
41 | return type.IsImplementationOf();
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Data/NHibernateMaps/Conventions/ForeignKeyConvention.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FluentNHibernate;
3 |
4 | namespace SharpArchitecture.MultiTenant.Data.NHibernateMaps.Conventions
5 | {
6 | public class ForeignKeyConvention : FluentNHibernate.Conventions.ForeignKeyConvention
7 | {
8 | protected override string GetKeyName(Member property, Type type)
9 | {
10 | if (property == null)
11 | return type.Name + "Fk";
12 |
13 | return property.Name + "Fk";
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Data/NHibernateMaps/Conventions/HasManyConvention.cs:
--------------------------------------------------------------------------------
1 | using FluentNHibernate.Conventions;
2 |
3 | namespace SharpArchitecture.MultiTenant.Data.NHibernateMaps.Conventions
4 | {
5 | public class HasManyConvention : IHasManyConvention
6 | {
7 | public void Apply(FluentNHibernate.Conventions.Instances.IOneToManyCollectionInstance instance)
8 | {
9 | instance.Key.Column(instance.EntityType.Name + "Fk");
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Data/NHibernateMaps/Conventions/HasManyToManyConvention.cs:
--------------------------------------------------------------------------------
1 | using FluentNHibernate.Conventions;
2 | using FluentNHibernate.Conventions.Instances;
3 |
4 | namespace SharpArchitecture.MultiTenant.Data.NHibernateMaps.Conventions
5 | {
6 | public class HasManyToManyConvention : IHasManyToManyConvention
7 | {
8 | public void Apply(IManyToManyCollectionInstance instance)
9 | {
10 | instance.Cascade.SaveUpdate();
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Data/NHibernateMaps/Conventions/ManyToManyTableNameConvention.cs:
--------------------------------------------------------------------------------
1 | using FluentNHibernate.Conventions.Inspections;
2 |
3 | namespace SharpArchitecture.MultiTenant.Data.NHibernateMaps.Conventions
4 | {
5 | public class ManyToManyTableNameConvention : FluentNHibernate.Conventions.ManyToManyTableNameConvention
6 | {
7 | protected override string GetBiDirectionalTableName(IManyToManyCollectionInspector collection,
8 | IManyToManyCollectionInspector otherSide)
9 | {
10 |
11 | return Inflector.Net.Inflector.Pluralize(collection.EntityType.Name) + "_" +
12 | Inflector.Net.Inflector.Pluralize(otherSide.EntityType.Name);
13 | }
14 |
15 | protected override string GetUniDirectionalTableName(IManyToManyCollectionInspector collection)
16 | {
17 | return Inflector.Net.Inflector.Pluralize(collection.EntityType.Name) + "_" +
18 | Inflector.Net.Inflector.Pluralize(collection.ChildType.Name);
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Data/NHibernateMaps/Conventions/PrimaryKeyConvention.cs:
--------------------------------------------------------------------------------
1 | using FluentNHibernate.Conventions;
2 |
3 | namespace SharpArchitecture.MultiTenant.Data.NHibernateMaps.Conventions
4 | {
5 | public class PrimaryKeyConvention : IIdConvention
6 | {
7 | public void Apply(FluentNHibernate.Conventions.Instances.IIdentityInstance instance)
8 | {
9 | instance.Column("Id");
10 | instance.UnsavedValue("0");
11 | instance.GeneratedBy.HiLo("1000");
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Data/NHibernateMaps/Conventions/ReferenceConvention.cs:
--------------------------------------------------------------------------------
1 | using FluentNHibernate.Conventions;
2 | using FluentNHibernate.Mapping;
3 |
4 | namespace SharpArchitecture.MultiTenant.Data.NHibernateMaps.Conventions
5 | {
6 | public class ReferenceConvention : IReferenceConvention
7 | {
8 | public void Apply(FluentNHibernate.Conventions.Instances.IManyToOneInstance instance)
9 | {
10 | instance.Column(instance.Property.Name + "Fk");
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Data/NHibernateMaps/Conventions/TableNameConvention.cs:
--------------------------------------------------------------------------------
1 | using FluentNHibernate.Conventions;
2 | using FluentNHibernate.Mapping;
3 |
4 | namespace SharpArchitecture.MultiTenant.Data.NHibernateMaps.Conventions
5 | {
6 | public class TableNameConvention : IClassConvention
7 | {
8 | public void Apply(FluentNHibernate.Conventions.Instances.IClassInstance instance)
9 | {
10 | instance.Table(Inflector.Net.Inflector.Pluralize(instance.EntityType.Name));
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Data/NHibernateMaps/MultiTenantAutoPersistenceModelGenerator.cs:
--------------------------------------------------------------------------------
1 | using FluentNHibernate.Automapping;
2 |
3 | namespace SharpArchitecture.MultiTenant.Data.NHibernateMaps
4 | {
5 | public class MultiTenantAutoPersistenceModelGenerator : AutoPersistenceModelGenerator
6 | {
7 | protected override IAutomappingConfiguration GetAutomappingConfiguration()
8 | {
9 | return new MultiTenantAutomappingConfiguration();
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Data/NHibernateMaps/MultiTenantAutomappingConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace SharpArchitecture.MultiTenant.Data.NHibernateMaps
4 | {
5 | ///
6 | ///
7 | ///
8 | public class MultiTenantAutomappingConfiguration : AutomappingConfiguration
9 | {
10 | public override bool ShouldMap(Type type)
11 | {
12 | return IsMultiTenantEntity(type);
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Data/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("SharpArchitecture.MultiTenant.Data")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyProduct("SharpArchitecture.MultiTenant.Data")]
11 |
12 | // The following GUID is for the ID of the typelib if this project is exposed to COM
13 | [assembly: Guid("a21e98c6-2e40-442f-8a9d-9795741000b7")]
14 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Data/SharpArchitecture.MultiTenant.Data.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 |
7 |
8 | 2.0
9 | {63E9AECE-3385-44F0-BDF9-4C01DD3C0647}
10 | Library
11 | Properties
12 | SharpArchitecture.MultiTenant.Data
13 | SharpArchitecture.MultiTenant.Data
14 | v4.0
15 | 512
16 |
17 |
18 |
19 | true
20 | full
21 | false
22 | bin\Debug\
23 | DEBUG;TRACE
24 | prompt
25 | 4
26 |
27 |
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 | ..\..\lib\FluentNHibernate.dll
38 |
39 |
40 | ..\..\lib\NHibernate.dll
41 |
42 |
43 | ..\..\lib\SharpArch.Domain.dll
44 |
45 |
46 | ..\..\lib\SharpArch.NHibernate.dll
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | False
59 | ..\..\lib\Inflector.Net.dll
60 |
61 |
62 | False
63 | ..\..\lib\Microsoft.Practices.ServiceLocation.dll
64 |
65 |
66 |
67 |
68 | Properties\CommonAssemblyInfo.cs
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | {7696B4F6-2A10-40C4-A1E2-B9768182588C}
77 | SharpArchitecture.MultiTenant.Core
78 |
79 |
80 | {F5A0D972-5870-4EB8-8400-F7F2435AE11C}
81 | SharpArchitecture.MultiTenant.Framework
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
103 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Framework/Contracts/IMultiTenantEntity.cs:
--------------------------------------------------------------------------------
1 | namespace SharpArchitecture.MultiTenant.Framework.Contracts
2 | {
3 | ///
4 | /// Marker interface for multi tenant entities.
5 | ///
6 | public interface IMultiTenantEntity {}
7 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Framework/Contracts/IMultiTenantQuery.cs:
--------------------------------------------------------------------------------
1 | namespace SharpArchitecture.MultiTenant.Framework.Contracts
2 | {
3 | public interface IMultiTenantQuery { }
4 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Framework/Contracts/IMultiTenantRepository.cs:
--------------------------------------------------------------------------------
1 | namespace SharpArchitecture.MultiTenant.Framework.Contracts
2 | {
3 | public interface IMultiTenantRepository { }
4 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Framework/Extensions/TypeExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace SharpArchitecture.MultiTenant.Framework.Extensions
5 | {
6 | public static class TypeExtensions
7 | {
8 | public static bool IsImplementationOf(this Type type)
9 | {
10 | return type.GetInterfaces().Any(x => x == typeof(T));
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Framework/NHibernate/MultiTenantSessionFactoryKeyProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using SharpArch.NHibernate;
4 | using SharpArchitecture.MultiTenant.Framework.Contracts;
5 | using SharpArchitecture.MultiTenant.Framework.Extensions;
6 | using SharpArchitecture.MultiTenant.Framework.Services;
7 |
8 | namespace SharpArchitecture.MultiTenant.Framework.NHibernate
9 | {
10 | public class MultiTenantSessionFactoryKeyProvider : ISessionFactoryKeyProvider
11 | {
12 | private readonly ITenantContext _tenantContext;
13 |
14 | public MultiTenantSessionFactoryKeyProvider(ITenantContext tenantContext)
15 | {
16 | _tenantContext = tenantContext;
17 | }
18 |
19 | public string GetKey()
20 | {
21 | var key = _tenantContext.Key;
22 | return string.IsNullOrEmpty(key) ? NHibernateSession.DefaultFactoryKey : key;
23 | }
24 |
25 | public string GetKeyFrom(object anObject)
26 | {
27 | var type = anObject.GetType();
28 | var isMultiTenant = type.IsImplementationOf() ||
29 | type.IsImplementationOf() ||
30 | IsRepositoryForMultiTenantEntity(type);
31 | return isMultiTenant
32 | ? GetKey()
33 | : NHibernateSession.DefaultFactoryKey;
34 | }
35 |
36 | public bool IsRepositoryForMultiTenantEntity(Type type)
37 | {
38 | if (!type.IsGenericType) {
39 | return false;
40 | }
41 |
42 | var genericTypes = type.GetGenericArguments();
43 | if (!genericTypes.Any()) {
44 | return false;
45 | }
46 |
47 | var firstGenericType = genericTypes[0];
48 | return firstGenericType.IsImplementationOf();
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Framework/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("SharpArchitecture.MultiTenant.Framework")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft")]
12 | [assembly: AssemblyProduct("SharpArchitecture.MultiTenant.Framework")]
13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("dd4740d5-bf64-43fc-a1c2-3343efcb9a02")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Framework/Services/ITenantContext.cs:
--------------------------------------------------------------------------------
1 | namespace SharpArchitecture.MultiTenant.Framework.Services
2 | {
3 | public interface ITenantContext
4 | {
5 | string Key { get; set; }
6 | }
7 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Framework/SharpArchitecture.MultiTenant.Framework.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.30703
7 | 2.0
8 | {F5A0D972-5870-4EB8-8400-F7F2435AE11C}
9 | Library
10 | Properties
11 | SharpArchitecture.MultiTenant.Framework
12 | SharpArchitecture.MultiTenant.Framework
13 | v4.0
14 | 512
15 |
16 |
17 |
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 | ..\..\lib\SharpArch.NHibernate.dll
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | ..\..\lib\FluentNHibernate.dll
48 |
49 |
50 | False
51 | ..\..\lib\Microsoft.Practices.ServiceLocation.dll
52 |
53 |
54 | ..\..\lib\NHibernate.dll
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
74 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web.Controllers/ControllerEnums.cs:
--------------------------------------------------------------------------------
1 | namespace SharpArchitecture.MultiTenant.Web.Controllers
2 | {
3 | public class ControllerEnums
4 | {
5 | public enum GlobalViewDataProperty
6 | {
7 | PageMessage
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web.Controllers/Customers/Queries/ICustomerListQuery.cs:
--------------------------------------------------------------------------------
1 | using MvcContrib.Pagination;
2 | using SharpArchitecture.MultiTenant.Framework.Contracts;
3 | using SharpArchitecture.MultiTenant.Web.Controllers.Customers.ViewModels;
4 |
5 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Customers.Queries
6 | {
7 | public interface ICustomerListQuery : IMultiTenantQuery
8 | {
9 | IPagination GetPagedList(int pageIndex, int pageSize);
10 | }
11 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web.Controllers/Customers/Queries/Impl/CustomerListQuery.cs:
--------------------------------------------------------------------------------
1 | using MvcContrib.Pagination;
2 | using NHibernate.Transform;
3 | using SharpArch.NHibernate;
4 | using SharpArchitecture.MultiTenant.Core;
5 | using SharpArchitecture.MultiTenant.Web.Controllers.Customers.ViewModels;
6 |
7 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Customers.Queries.Impl
8 | {
9 | public class CustomerListQuery : NHibernateQuery, ICustomerListQuery
10 | {
11 | public IPagination GetPagedList(int pageIndex, int pageSize)
12 | {
13 | var query = Session.QueryOver()
14 | .OrderBy(customer => customer.Code).Asc;
15 |
16 | var countQuery = query.ToRowCountQuery();
17 | var totalCount = countQuery.FutureValue();
18 |
19 | var firstResult = (pageIndex - 1) * pageSize;
20 |
21 | CustomerViewModel viewModel = null;
22 | var viewModels = query.SelectList(list => list
23 | .Select(mission => mission.Id).WithAlias(() => viewModel.Id)
24 | .Select(mission => mission.Code).WithAlias(() => viewModel.Code)
25 | .Select(mission => mission.Name).WithAlias(() => viewModel.Name))
26 | .TransformUsing(Transformers.AliasToBean(typeof(CustomerViewModel)))
27 | .Skip(firstResult)
28 | .Take(pageSize)
29 | .Future();
30 |
31 | return new CustomPagination(viewModels, pageIndex, pageSize, totalCount.Value);
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web.Controllers/Customers/ViewModels/CustomerFormViewModel.cs:
--------------------------------------------------------------------------------
1 | using SharpArchitecture.MultiTenant.Core;
2 |
3 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Customers.ViewModels
4 | {
5 | public class CustomerFormViewModel
6 | {
7 | public CustomerFormViewModel() {}
8 |
9 | public CustomerFormViewModel(Customer customer)
10 | {
11 | Id = customer.Id;
12 | Code = customer.Code;
13 | Name = customer.Name;
14 | }
15 |
16 | public int Id { get; set; }
17 | public string Code { get; set; }
18 | public string Name { get; set; }
19 | }
20 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web.Controllers/Customers/ViewModels/CustomerListViewModel.cs:
--------------------------------------------------------------------------------
1 | using MvcContrib.Pagination;
2 |
3 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Customers.ViewModels
4 | {
5 | public class CustomerListViewModel
6 | {
7 | public IPagination Customers { get; set; }
8 | }
9 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web.Controllers/Customers/ViewModels/CustomerViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Customers.ViewModels
2 | {
3 | public class CustomerViewModel
4 | {
5 | public int Id { get; set; }
6 | public string Code { get; set; }
7 | public string Name { get; set; }
8 | }
9 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web.Controllers/Customers/ViewModels/ImportCustomersFormViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Customers.ViewModels
4 | {
5 | public class ImportCustomersFormViewModel
6 | {
7 | public Guid UploadKey { get; set; }
8 | }
9 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web.Controllers/HomeController.cs:
--------------------------------------------------------------------------------
1 | using System.Web.Mvc;
2 |
3 | namespace SharpArchitecture.MultiTenant.Web.Controllers
4 | {
5 | [HandleError]
6 | public class HomeController : Controller
7 | {
8 | public ActionResult Index()
9 | {
10 | return View();
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web.Controllers/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("SharpArchitecture.MultiTenant.Web.Controllers")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyProduct("SharpArchitecture.MultiTenant.Web.Controllers")]
11 |
12 | // The following GUID is for the ID of the typelib if this project is exposed to COM
13 | [assembly: Guid("4789c96f-3d6f-40f0-8744-a05e2854d494")]
14 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web.Controllers/RouteRegistrar.cs:
--------------------------------------------------------------------------------
1 | using System.Web.Mvc;
2 | using System.Web.Routing;
3 |
4 | namespace SharpArchitecture.MultiTenant.Web.Controllers
5 | {
6 | public class RouteRegistrar
7 | {
8 | public static void RegisterRoutesTo(RouteCollection routes)
9 | {
10 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
11 | routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });
12 |
13 | routes.MapRoute(
14 | "Default", // Route name
15 | "{controller}/{action}/{id}", // URL with parameters
16 | new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
17 | );
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web.Controllers/SharpArchitecture.MultiTenant.Web.Controllers.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 |
7 |
8 | 2.0
9 | {518B2E4B-2B9B-48EF-8736-DDB6A0F78E79}
10 | Library
11 | Properties
12 | SharpArchitecture.MultiTenant.Web.Controllers
13 | SharpArchitecture.MultiTenant.Web.Controllers
14 | v4.0
15 | 512
16 |
17 |
18 |
19 | true
20 | full
21 | false
22 | bin\Debug\
23 | DEBUG;TRACE
24 | prompt
25 | 4
26 |
27 |
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 | False
38 | ..\..\lib\Microsoft.Practices.ServiceLocation.dll
39 |
40 |
41 | ..\..\lib\MvcContrib.dll
42 |
43 |
44 | ..\..\lib\NHibernate.dll
45 |
46 |
47 | ..\..\lib\SharpArch.Domain.dll
48 |
49 |
50 | ..\..\lib\SharpArch.NHibernate.dll
51 |
52 |
53 |
54 | 3.5
55 |
56 |
57 |
58 |
59 |
60 | False
61 | ..\..\lib\System.Web.Mvc.dll
62 |
63 |
64 | 3.5
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 | Properties\CommonAssemblyInfo.cs
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 | {7696B4F6-2A10-40C4-A1E2-B9768182588C}
94 | SharpArchitecture-MultiTenant.Core
95 |
96 |
97 | {EA00777D-3D7A-4406-8BFB-E5A90CF0E8A9}
98 | SharpArchitecture-MultiTenant.ApplicationServices
99 |
100 |
101 | {63E9AECE-3385-44F0-BDF9-4C01DD3C0647}
102 | SharpArchitecture.MultiTenant.Data
103 |
104 |
105 | {F5A0D972-5870-4EB8-8400-F7F2435AE11C}
106 | SharpArchitecture.MultiTenant.Framework
107 |
108 |
109 |
110 |
111 |
118 |
119 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web.Controllers/TempDataExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Web.Mvc;
2 |
3 | namespace SharpArchitecture.MultiTenant.Web.Controllers
4 | {
5 | ///
6 | /// Extension methods for TempDataDictionary
7 | ///
8 | public static class TempDataExtensions
9 | {
10 | ///
11 | /// Adds an object to the dictionary using the type name as the key
12 | ///
13 | ///
14 | /// The temp data.
15 | ///
16 | ///
17 | /// The obj to add.
18 | ///
19 | public static void SafeAdd(this TempDataDictionary tempData, object obj)
20 | {
21 | tempData.Add(obj.GetType().Name, obj);
22 | }
23 |
24 | ///
25 | /// Gets an object from the dictionary using the type name as the key
26 | ///
27 | ///
28 | /// The temp data.
29 | ///
30 | ///
31 | /// The object type
32 | ///
33 | ///
34 | /// The object
35 | ///
36 | public static T SafeGet(this TempDataDictionary tempData)
37 | {
38 | object obj;
39 |
40 | if (tempData.TryGetValue(typeof(T).Name, out obj))
41 | {
42 | return (T)obj;
43 | }
44 |
45 | return default(T);
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web.Controllers/Tenants/Queries/ITenantListQuery.cs:
--------------------------------------------------------------------------------
1 | using MvcContrib.Pagination;
2 | using SharpArchitecture.MultiTenant.Web.Controllers.Tenants.ViewModels;
3 |
4 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Tenants.Queries
5 | {
6 | public interface ITenantListQuery
7 | {
8 | IPagination GetPagedList(int pageIndex, int pageSize);
9 | }
10 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web.Controllers/Tenants/Queries/Impl/TenantListQuery.cs:
--------------------------------------------------------------------------------
1 | using MvcContrib.Pagination;
2 | using NHibernate.Transform;
3 | using SharpArch.NHibernate;
4 | using SharpArchitecture.MultiTenant.Core;
5 | using SharpArchitecture.MultiTenant.Web.Controllers.Tenants.ViewModels;
6 |
7 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Tenants.Queries.Impl
8 | {
9 | public class TenantListQuery : NHibernateQuery, ITenantListQuery
10 | {
11 | public IPagination GetPagedList(int pageIndex, int pageSize)
12 | {
13 | var query = Session.QueryOver()
14 | .OrderBy(customer => customer.Name).Asc;
15 |
16 | var countQuery = query.ToRowCountQuery();
17 | var totalCount = countQuery.FutureValue();
18 |
19 | var firstResult = (pageIndex - 1) * pageSize;
20 | TenantViewModel viewModel = null;
21 | var viewModels = query.SelectList(list => list
22 | .Select(mission => mission.Id).WithAlias(() => viewModel.Id)
23 | .Select(mission => mission.Name).WithAlias(() => viewModel.Name)
24 | .Select(mission => mission.Domain).WithAlias(() => viewModel.Domain)
25 | .Select(mission => mission.ConnectionString).WithAlias(() => viewModel.ConnectionString))
26 | .TransformUsing(Transformers.AliasToBean(typeof(TenantViewModel)))
27 | .Skip(firstResult)
28 | .Take(pageSize)
29 | .Future();
30 |
31 | return new CustomPagination(viewModels, pageIndex, pageSize, totalCount.Value);
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web.Controllers/Tenants/TenantsController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Web.Mvc;
3 | using MvcContrib;
4 | using MvcContrib.Filters;
5 | using SharpArch.Domain.PersistenceSupport;
6 | using SharpArch.NHibernate.Web.Mvc;
7 | using SharpArchitecture.MultiTenant.Core;
8 | using SharpArchitecture.MultiTenant.Web.Controllers.Tenants.Queries;
9 | using SharpArchitecture.MultiTenant.Web.Controllers.Tenants.ViewModels;
10 |
11 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Tenants
12 | {
13 | public class TenantsController : Controller
14 | {
15 | private const int DefaultPageSize = 20;
16 | private readonly IRepository _tenantRepository;
17 | private readonly ITenantListQuery _tenantListQuery;
18 |
19 | public TenantsController(IRepository tenantRepository, ITenantListQuery tenantListQuery)
20 | {
21 | _tenantRepository = tenantRepository;
22 | _tenantListQuery = tenantListQuery;
23 | }
24 |
25 | [HttpGet]
26 | [Transaction]
27 | public ActionResult Index(int? page)
28 | {
29 | var viewModels = _tenantListQuery.GetPagedList(page ?? 1, DefaultPageSize);
30 | var viewModel = new TenantListViewModel { Tenants = viewModels };
31 | return View(viewModel);
32 | }
33 |
34 | [HttpGet]
35 | [ModelStateToTempData]
36 | [Transaction]
37 | public ActionResult Create()
38 | {
39 | var viewModel = TempData.SafeGet() ?? new TenantFormViewModel();
40 | return View(viewModel);
41 | }
42 |
43 | [HttpPost]
44 | [ValidateAntiForgeryToken]
45 | [ModelStateToTempData]
46 | [Transaction]
47 | public ActionResult Create(TenantFormViewModel viewModel)
48 | {
49 | if (!ViewData.ModelState.IsValid) {
50 | TempData.SafeAdd(viewModel);
51 | return this.RedirectToAction(c => c.Create());
52 | }
53 |
54 | try {
55 | var tenant = new Tenant { Name = viewModel.Name, Domain = viewModel.Domain, ConnectionString = viewModel.ConnectionString};
56 | _tenantRepository.SaveOrUpdate(tenant);
57 | TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = string.Format("Successfully created tenant '{0}'", tenant.Name);
58 | }
59 | catch (Exception ex) {
60 | TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = string.Format("An error occurred creating the tenant: {0}", ex.Message);
61 | return this.RedirectToAction(c => c.Create());
62 | }
63 |
64 | return this.RedirectToAction(c => c.Index(null));
65 | }
66 |
67 | [HttpGet]
68 | [ModelStateToTempData]
69 | [Transaction]
70 | public ActionResult Edit(int id)
71 | {
72 | var tenant = _tenantRepository.Get(id);
73 | var viewModel = new TenantFormViewModel(tenant);
74 | return View(viewModel);
75 | }
76 |
77 | [HttpPost]
78 | [ValidateAntiForgeryToken]
79 | [ModelStateToTempData]
80 | [Transaction]
81 | public ActionResult Edit(TenantFormViewModel viewModel)
82 | {
83 | if (!ViewData.ModelState.IsValid) {
84 | return this.RedirectToAction(c => c.Edit(viewModel.Id));
85 | }
86 |
87 | try {
88 | var tenant = _tenantRepository.Get(viewModel.Id);
89 | tenant.Name = viewModel.Name;
90 | tenant.Domain = viewModel.Domain;
91 | tenant.ConnectionString= viewModel.ConnectionString;
92 |
93 | _tenantRepository.SaveOrUpdate(tenant);
94 | TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = string.Format("Successfully updated tenant '{0}'", tenant.Name);
95 | }
96 | catch (Exception ex) {
97 | TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = string.Format("An error occurred updating the tenant: {0}", ex.Message);
98 | return this.RedirectToAction(c => c.Edit(viewModel.Id));
99 | }
100 |
101 | return this.RedirectToAction(c => c.Index(null));
102 | }
103 |
104 | [HttpGet]
105 | [ModelStateToTempData]
106 | [Transaction]
107 | public ActionResult Delete(int id)
108 | {
109 | var tenant = _tenantRepository.Get(id);
110 | var viewModel = new TenantFormViewModel(tenant);
111 | return View(viewModel);
112 | }
113 |
114 | [HttpPost]
115 | [ValidateAntiForgeryToken]
116 | [ModelStateToTempData]
117 | [Transaction]
118 | public ActionResult Delete(TenantFormViewModel viewModel)
119 | {
120 | if (!ViewData.ModelState.IsValid) {
121 | return this.RedirectToAction(c => c.Edit(viewModel.Id));
122 | }
123 |
124 | try {
125 | var tenant = _tenantRepository.Get(viewModel.Id);
126 | _tenantRepository.Delete(tenant);
127 | TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = string.Format("Successfully deleted tenant '{0}'", tenant.Name);
128 | }
129 | catch (Exception ex) {
130 | TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = string.Format("An error occurred deleting the tenant: {0}", ex.Message);
131 | return this.RedirectToAction(c => c.Edit(viewModel.Id));
132 | }
133 |
134 | return this.RedirectToAction(c => c.Index(null));
135 | }
136 | }
137 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web.Controllers/Tenants/ViewModels/TenantFormViewModel.cs:
--------------------------------------------------------------------------------
1 | using SharpArchitecture.MultiTenant.Core;
2 |
3 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Tenants.ViewModels
4 | {
5 | public class TenantFormViewModel
6 | {
7 | public TenantFormViewModel() {}
8 |
9 | public TenantFormViewModel(Tenant tenant)
10 | {
11 | Id = tenant.Id;
12 | Name = tenant.Name;
13 | Domain = tenant.Domain;
14 | ConnectionString = tenant.ConnectionString;
15 | }
16 |
17 | public int Id { get; set; }
18 | public string Name { get; set; }
19 | public string Domain { get; set; }
20 | public string ConnectionString { get; set; }
21 | }
22 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web.Controllers/Tenants/ViewModels/TenantListViewModel.cs:
--------------------------------------------------------------------------------
1 | using MvcContrib.Pagination;
2 |
3 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Tenants.ViewModels
4 | {
5 | public class TenantListViewModel
6 | {
7 | public IPagination Tenants { get; set; }
8 | }
9 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web.Controllers/Tenants/ViewModels/TenantViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Tenants.ViewModels
2 | {
3 | public class TenantViewModel
4 | {
5 | public int Id { get; set; }
6 | public string Name { get; set; }
7 | public string Domain { get; set; }
8 | public string ConnectionString { get; set; }
9 | }
10 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/App_Data/dummy.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/CastleWindsor/ComponentRegistrar.cs:
--------------------------------------------------------------------------------
1 | using Castle.Core;
2 | using Castle.Windsor;
3 | using SharpArch.Domain.Commands;
4 | using Castle.MicroKernel.Registration;
5 | using SharpArch.Domain.PersistenceSupport;
6 | using SharpArch.NHibernate;
7 | using SharpArch.NHibernate.Contracts.Repositories;
8 | using SharpArch.Web.Mvc.Castle;
9 | using SharpArchitecture.MultiTenant.Framework.NHibernate;
10 | using SharpArchitecture.MultiTenant.Framework.Services;
11 | using SharpArchitecture.MultiTenant.Web.Services;
12 |
13 | namespace SharpArchitecture.MultiTenant.Web.CastleWindsor
14 | {
15 | public class ComponentRegistrar
16 | {
17 | public static void AddComponentsTo(IWindsorContainer container)
18 | {
19 | AddGenericRepositoriesTo(container);
20 | AddCustomRepositoriesTo(container);
21 | AddQueriesTo(container);
22 | AddApplicationServicesTo(container);
23 | AddCommandHandlersTo(container);
24 | AddMultiTenantServicesTo(container);
25 | }
26 |
27 | private static void AddApplicationServicesTo(IWindsorContainer container)
28 | {
29 | container.Register(
30 | AllTypes
31 | .FromAssemblyNamed("SharpArchitecture.MultiTenant.ApplicationServices")
32 | .Pick()
33 | .If(f => !string.IsNullOrEmpty(f.Namespace) && !f.Namespace.Contains(".Commands"))
34 | .WithService.FirstInterface());
35 | }
36 |
37 | private static void AddCommandHandlersTo(IWindsorContainer container)
38 | {
39 | container.Register(
40 | AllTypes.FromAssemblyNamed("SharpArchitecture.MultiTenant.ApplicationServices").Pick()
41 | .If(f => !string.IsNullOrEmpty(f.Namespace) && f.Namespace.Contains(".CommandHandlers"))
42 | .Configure(c => c.LifeStyle.Is(LifestyleType.Transient))
43 | .WithService.FirstInterface());
44 | }
45 |
46 | private static void AddCustomRepositoriesTo(IWindsorContainer container)
47 | {
48 | container.Register(
49 | AllTypes
50 | .FromAssemblyNamed("SharpArchitecture.MultiTenant.Data")
51 | .Pick()
52 | .WithService.FirstNonGenericCoreInterface("SharpArchitecture.MultiTenant.Core"));
53 | }
54 |
55 | private static void AddGenericRepositoriesTo(IWindsorContainer container)
56 | {
57 | container.Register(
58 | Component.For(typeof(IQuery<>))
59 | .ImplementedBy(typeof(NHibernateQuery<>))
60 | .Named("NHibernateQuery"));
61 |
62 | container.Register(
63 | Component
64 | .For(typeof(IEntityDuplicateChecker))
65 | .ImplementedBy(typeof(EntityDuplicateChecker))
66 | .Named("entityDuplicateChecker"));
67 |
68 | container.Register(
69 | Component
70 | .For(typeof(IRepository<>))
71 | .ImplementedBy(typeof(NHibernateRepository<>))
72 | .Named("nhibernateRepositoryType"));
73 |
74 | container.Register(
75 | Component
76 | .For(typeof(IRepositoryWithTypedId<,>))
77 | .ImplementedBy(typeof(NHibernateRepositoryWithTypedId<,>))
78 | .Named("nhibernateRepositoryWithTypedId"));
79 |
80 | container.Register(
81 | Component
82 | .For(typeof(ISessionFactoryKeyProvider))
83 | .ImplementedBy(typeof(MultiTenantSessionFactoryKeyProvider))
84 | .Named("sessionFactoryKeyProvider"));
85 |
86 | container.Register(
87 | Component
88 | .For(typeof(ICommandProcessor))
89 | .ImplementedBy(typeof(CommandProcessor))
90 | .Named("CommandProcessor"));
91 | }
92 |
93 | private static void AddQueriesTo(IWindsorContainer container)
94 | {
95 | container.Register(
96 | AllTypes.FromAssemblyNamed("SharpArchitecture.MultiTenant.Web").Pick()
97 | .If(f => !string.IsNullOrEmpty(f.Namespace) && f.Namespace.Contains(".Queries"))
98 | .Configure(c => c.LifeStyle.Is(LifestyleType.Transient))
99 | .WithService.FirstNonGenericCoreInterface("SharpArchitecture.MultiTenant.Web.Controllers"));
100 | }
101 |
102 | private static void AddMultiTenantServicesTo(IWindsorContainer container)
103 | {
104 | container.Register(
105 | Component
106 | .For(typeof(ITenantContext))
107 | .ImplementedBy(typeof(TenantContext)));
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Content/Images/cancel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/app/SharpArchitecture-MultiTenant.Web/Content/Images/cancel.png
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Content/Images/sharp_arch.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/app/SharpArchitecture-MultiTenant.Web/Content/Images/sharp_arch.jpg
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Content/Images/sharp_arch_small.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/app/SharpArchitecture-MultiTenant.Web/Content/Images/sharp_arch_small.gif
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Controllers/ControllerEnums.cs:
--------------------------------------------------------------------------------
1 | namespace SharpArchitecture.MultiTenant.Web.Controllers
2 | {
3 | public class ControllerEnums
4 | {
5 | public enum GlobalViewDataProperty
6 | {
7 | PageMessage
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Controllers/Customers/Queries/ICustomerListQuery.cs:
--------------------------------------------------------------------------------
1 | using MvcContrib.Pagination;
2 | using SharpArchitecture.MultiTenant.Framework.Contracts;
3 | using SharpArchitecture.MultiTenant.Web.Controllers.Customers.ViewModels;
4 |
5 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Customers.Queries
6 | {
7 | public interface ICustomerListQuery : IMultiTenantQuery
8 | {
9 | IPagination GetPagedList(int pageIndex, int pageSize);
10 | }
11 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Controllers/Customers/Queries/Impl/CustomerListQuery.cs:
--------------------------------------------------------------------------------
1 | using MvcContrib.Pagination;
2 | using NHibernate.Transform;
3 | using SharpArch.NHibernate;
4 | using SharpArchitecture.MultiTenant.Core;
5 | using SharpArchitecture.MultiTenant.Web.Controllers.Customers.ViewModels;
6 |
7 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Customers.Queries.Impl
8 | {
9 | public class CustomerListQuery : NHibernateQuery, ICustomerListQuery
10 | {
11 | public IPagination GetPagedList(int pageIndex, int pageSize)
12 | {
13 | var query = Session.QueryOver()
14 | .OrderBy(customer => customer.Code).Asc;
15 |
16 | var countQuery = query.ToRowCountQuery();
17 | var totalCount = countQuery.FutureValue();
18 |
19 | var firstResult = (pageIndex - 1) * pageSize;
20 |
21 | CustomerViewModel viewModel = null;
22 | var viewModels = query.SelectList(list => list
23 | .Select(mission => mission.Id).WithAlias(() => viewModel.Id)
24 | .Select(mission => mission.Code).WithAlias(() => viewModel.Code)
25 | .Select(mission => mission.Name).WithAlias(() => viewModel.Name))
26 | .TransformUsing(Transformers.AliasToBean(typeof(CustomerViewModel)))
27 | .Skip(firstResult)
28 | .Take(pageSize)
29 | .Future();
30 |
31 | return new CustomPagination(viewModels, pageIndex, pageSize, totalCount.Value);
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Controllers/Customers/ViewModels/CustomerFormViewModel.cs:
--------------------------------------------------------------------------------
1 | using SharpArchitecture.MultiTenant.Core;
2 |
3 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Customers.ViewModels
4 | {
5 | public class CustomerFormViewModel
6 | {
7 | public CustomerFormViewModel() {}
8 |
9 | public CustomerFormViewModel(Customer customer)
10 | {
11 | Id = customer.Id;
12 | Code = customer.Code;
13 | Name = customer.Name;
14 | }
15 |
16 | public int Id { get; set; }
17 | public string Code { get; set; }
18 | public string Name { get; set; }
19 | }
20 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Controllers/Customers/ViewModels/CustomerListViewModel.cs:
--------------------------------------------------------------------------------
1 | using MvcContrib.Pagination;
2 |
3 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Customers.ViewModels
4 | {
5 | public class CustomerListViewModel
6 | {
7 | public IPagination Customers { get; set; }
8 | }
9 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Controllers/Customers/ViewModels/CustomerViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Customers.ViewModels
2 | {
3 | public class CustomerViewModel
4 | {
5 | public int Id { get; set; }
6 | public string Code { get; set; }
7 | public string Name { get; set; }
8 | }
9 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Controllers/Customers/ViewModels/ImportCustomersFormViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Customers.ViewModels
4 | {
5 | public class ImportCustomersFormViewModel
6 | {
7 | public Guid UploadKey { get; set; }
8 | }
9 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Controllers/HomeController.cs:
--------------------------------------------------------------------------------
1 | using System.Web.Mvc;
2 |
3 | namespace SharpArchitecture.MultiTenant.Web.Controllers
4 | {
5 | [HandleError]
6 | public class HomeController : Controller
7 | {
8 | public ActionResult Index()
9 | {
10 | return View();
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Controllers/RouteRegistrar.cs:
--------------------------------------------------------------------------------
1 | using System.Web.Mvc;
2 | using System.Web.Routing;
3 |
4 | namespace SharpArchitecture.MultiTenant.Web.Controllers
5 | {
6 | public class RouteRegistrar
7 | {
8 | public static void RegisterRoutesTo(RouteCollection routes)
9 | {
10 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
11 | routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });
12 |
13 | routes.MapRoute(
14 | "Default", // Route name
15 | "{controller}/{action}/{id}", // URL with parameters
16 | new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
17 | );
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Controllers/Tenants/Queries/ITenantListQuery.cs:
--------------------------------------------------------------------------------
1 | using MvcContrib.Pagination;
2 | using SharpArchitecture.MultiTenant.Web.Controllers.Tenants.ViewModels;
3 |
4 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Tenants.Queries
5 | {
6 | public interface ITenantListQuery
7 | {
8 | IPagination GetPagedList(int pageIndex, int pageSize);
9 | }
10 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Controllers/Tenants/Queries/Impl/TenantListQuery.cs:
--------------------------------------------------------------------------------
1 | using MvcContrib.Pagination;
2 | using NHibernate.Transform;
3 | using SharpArch.NHibernate;
4 | using SharpArchitecture.MultiTenant.Core;
5 | using SharpArchitecture.MultiTenant.Web.Controllers.Tenants.ViewModels;
6 |
7 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Tenants.Queries.Impl
8 | {
9 | public class TenantListQuery : NHibernateQuery, ITenantListQuery
10 | {
11 | public IPagination GetPagedList(int pageIndex, int pageSize)
12 | {
13 | var query = Session.QueryOver()
14 | .OrderBy(customer => customer.Name).Asc;
15 |
16 | var countQuery = query.ToRowCountQuery();
17 | var totalCount = countQuery.FutureValue();
18 |
19 | var firstResult = (pageIndex - 1) * pageSize;
20 | TenantViewModel viewModel = null;
21 | var viewModels = query.SelectList(list => list
22 | .Select(mission => mission.Id).WithAlias(() => viewModel.Id)
23 | .Select(mission => mission.Name).WithAlias(() => viewModel.Name)
24 | .Select(mission => mission.Domain).WithAlias(() => viewModel.Domain)
25 | .Select(mission => mission.ConnectionString).WithAlias(() => viewModel.ConnectionString))
26 | .TransformUsing(Transformers.AliasToBean(typeof(TenantViewModel)))
27 | .Skip(firstResult)
28 | .Take(pageSize)
29 | .Future();
30 |
31 | return new CustomPagination(viewModels, pageIndex, pageSize, totalCount.Value);
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Controllers/Tenants/TenantsController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Web.Mvc;
3 | using MvcContrib;
4 | using MvcContrib.Filters;
5 | using SharpArch.Domain.PersistenceSupport;
6 | using SharpArch.NHibernate.Web.Mvc;
7 | using SharpArchitecture.MultiTenant.Core;
8 | using SharpArchitecture.MultiTenant.Web.Controllers.Tenants.Queries;
9 | using SharpArchitecture.MultiTenant.Web.Controllers.Tenants.ViewModels;
10 |
11 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Tenants
12 | {
13 | public class TenantsController : Controller
14 | {
15 | private const int DefaultPageSize = 20;
16 | private readonly IRepository _tenantRepository;
17 | private readonly ITenantListQuery _tenantListQuery;
18 |
19 | public TenantsController(IRepository tenantRepository, ITenantListQuery tenantListQuery)
20 | {
21 | _tenantRepository = tenantRepository;
22 | _tenantListQuery = tenantListQuery;
23 | }
24 |
25 | [HttpGet]
26 | [Transaction]
27 | public ActionResult Index(int? page)
28 | {
29 | var viewModels = _tenantListQuery.GetPagedList(page ?? 1, DefaultPageSize);
30 | var viewModel = new TenantListViewModel { Tenants = viewModels };
31 | return View(viewModel);
32 | }
33 |
34 | [HttpGet]
35 | [ModelStateToTempData]
36 | [Transaction]
37 | public ActionResult Create()
38 | {
39 | var viewModel = TempData.SafeGet() ?? new TenantFormViewModel();
40 | return View(viewModel);
41 | }
42 |
43 | [HttpPost]
44 | [ValidateAntiForgeryToken]
45 | [ModelStateToTempData]
46 | [Transaction]
47 | public ActionResult Create(TenantFormViewModel viewModel)
48 | {
49 | if (!ViewData.ModelState.IsValid) {
50 | TempData.SafeAdd(viewModel);
51 | return this.RedirectToAction(c => c.Create());
52 | }
53 |
54 | try {
55 | var tenant = new Tenant { Name = viewModel.Name, Domain = viewModel.Domain, ConnectionString = viewModel.ConnectionString};
56 | _tenantRepository.SaveOrUpdate(tenant);
57 | TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = string.Format("Successfully created tenant '{0}'", tenant.Name);
58 | }
59 | catch (Exception ex) {
60 | TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = string.Format("An error occurred creating the tenant: {0}", ex.Message);
61 | return this.RedirectToAction(c => c.Create());
62 | }
63 |
64 | return this.RedirectToAction(c => c.Index(null));
65 | }
66 |
67 | [HttpGet]
68 | [ModelStateToTempData]
69 | [Transaction]
70 | public ActionResult Edit(int id)
71 | {
72 | var tenant = _tenantRepository.Get(id);
73 | var viewModel = new TenantFormViewModel(tenant);
74 | return View(viewModel);
75 | }
76 |
77 | [HttpPost]
78 | [ValidateAntiForgeryToken]
79 | [ModelStateToTempData]
80 | [Transaction]
81 | public ActionResult Edit(TenantFormViewModel viewModel)
82 | {
83 | if (!ViewData.ModelState.IsValid) {
84 | return this.RedirectToAction(c => c.Edit(viewModel.Id));
85 | }
86 |
87 | try {
88 | var tenant = _tenantRepository.Get(viewModel.Id);
89 | tenant.Name = viewModel.Name;
90 | tenant.Domain = viewModel.Domain;
91 | tenant.ConnectionString= viewModel.ConnectionString;
92 |
93 | _tenantRepository.SaveOrUpdate(tenant);
94 | TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = string.Format("Successfully updated tenant '{0}'", tenant.Name);
95 | }
96 | catch (Exception ex) {
97 | TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = string.Format("An error occurred updating the tenant: {0}", ex.Message);
98 | return this.RedirectToAction(c => c.Edit(viewModel.Id));
99 | }
100 |
101 | return this.RedirectToAction(c => c.Index(null));
102 | }
103 |
104 | [HttpGet]
105 | [ModelStateToTempData]
106 | [Transaction]
107 | public ActionResult Delete(int id)
108 | {
109 | var tenant = _tenantRepository.Get(id);
110 | var viewModel = new TenantFormViewModel(tenant);
111 | return View(viewModel);
112 | }
113 |
114 | [HttpPost]
115 | [ValidateAntiForgeryToken]
116 | [ModelStateToTempData]
117 | [Transaction]
118 | public ActionResult Delete(TenantFormViewModel viewModel)
119 | {
120 | if (!ViewData.ModelState.IsValid) {
121 | return this.RedirectToAction(c => c.Edit(viewModel.Id));
122 | }
123 |
124 | try {
125 | var tenant = _tenantRepository.Get(viewModel.Id);
126 | _tenantRepository.Delete(tenant);
127 | TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = string.Format("Successfully deleted tenant '{0}'", tenant.Name);
128 | }
129 | catch (Exception ex) {
130 | TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = string.Format("An error occurred deleting the tenant: {0}", ex.Message);
131 | return this.RedirectToAction(c => c.Edit(viewModel.Id));
132 | }
133 |
134 | return this.RedirectToAction(c => c.Index(null));
135 | }
136 | }
137 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Controllers/Tenants/ViewModels/TenantFormViewModel.cs:
--------------------------------------------------------------------------------
1 | using SharpArchitecture.MultiTenant.Core;
2 |
3 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Tenants.ViewModels
4 | {
5 | public class TenantFormViewModel
6 | {
7 | public TenantFormViewModel() {}
8 |
9 | public TenantFormViewModel(Tenant tenant)
10 | {
11 | Id = tenant.Id;
12 | Name = tenant.Name;
13 | Domain = tenant.Domain;
14 | ConnectionString = tenant.ConnectionString;
15 | }
16 |
17 | public int Id { get; set; }
18 | public string Name { get; set; }
19 | public string Domain { get; set; }
20 | public string ConnectionString { get; set; }
21 | }
22 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Controllers/Tenants/ViewModels/TenantListViewModel.cs:
--------------------------------------------------------------------------------
1 | using MvcContrib.Pagination;
2 |
3 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Tenants.ViewModels
4 | {
5 | public class TenantListViewModel
6 | {
7 | public IPagination Tenants { get; set; }
8 | }
9 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Controllers/Tenants/ViewModels/TenantViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace SharpArchitecture.MultiTenant.Web.Controllers.Tenants.ViewModels
2 | {
3 | public class TenantViewModel
4 | {
5 | public int Id { get; set; }
6 | public string Name { get; set; }
7 | public string Domain { get; set; }
8 | public string ConnectionString { get; set; }
9 | }
10 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Default.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="SharpArchitecture.MultiTenant.Web._Default" %>
2 |
3 | <%-- Please do not delete this file. It is used to ensure that ASP.NET MVC is activated by IIS when a user makes a "/" request to the server. --%>
4 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Default.aspx.cs:
--------------------------------------------------------------------------------
1 | using System.Web;
2 | using System.Web.Mvc;
3 | using System.Web.UI;
4 |
5 | namespace SharpArchitecture.MultiTenant.Web
6 | {
7 | public partial class _Default : Page
8 | {
9 | public void Page_Load(object sender, System.EventArgs e)
10 | {
11 | HttpContext.Current.RewritePath(Request.ApplicationPath, false);
12 | IHttpHandler httpHandler = new MvcHttpHandler();
13 | httpHandler.ProcessRequest(HttpContext.Current);
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Global.asax:
--------------------------------------------------------------------------------
1 | <%@ Application Codebehind="Global.asax.cs" Inherits="SharpArchitecture.MultiTenant.Web.MvcApplication" Language="C#" %>
2 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/NHibernate.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Data Source=.\SQLEXPRESS;Initial Catalog=MultiTenantSample;Integrated Security=True;Application Name=SharpArchitecture.MultiTenant;
5 | NHibernate.Dialect.MsSql2005Dialect
6 | NHibernate.Connection.DriverConnectionProvider
7 | NHibernate.Driver.SqlClientDriver
8 | false
9 | auto
10 | 500
11 | NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle
12 |
13 |
14 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/NHibernate.tenant.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | NHibernate.Dialect.MsSql2005Dialect
5 | NHibernate.Connection.DriverConnectionProvider
6 | NHibernate.Driver.SqlClientDriver
7 | false
8 | auto
9 | 500
10 | NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle
11 |
12 |
13 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("SharpArchitecture.MultiTenant.Web")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyProduct("SharpArchitecture.MultiTenant.Web")]
11 |
12 | // The following GUID is for the ID of the typelib if this project is exposed to COM
13 | [assembly: Guid("b1b6e691-457c-4a17-816a-7221b9e81e34")]
14 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Scripts/expressInstall.swf:
--------------------------------------------------------------------------------
1 | CWS3 x��SMO�@;�1J���
2 | �=�b��h"�BAH���CU���!�����М{h/��R���z�W:�6$QSՖ�;owf�0]x�
������\)�����Qp(#}�m�\_��،���{��Cy��!ľ4Aϥ
3 | >��"A�������Hp�?������ط�� `�i�*�z��
4 |
5 | 6z��}q�n��>�� N���u ���(ۀFcm4B$M�1�G� 0�`4eq:����k�6� !�M�� �%��;�s�x�恇II�<8�G�zQ;���.w��>�]j_H�� nu]7�S���E_ɖʨ8b��"ܴ�&�¸mu��i�V�j!
N}aE���"H�����AD8�$>��Ui�)�oH&�����`h�$��9���e ��^>���C
��+'(h�kL�̤w {���}�5�j�w��ơ\'[r�ڗ9:*G��h�+�D,�:(Z�q�����G�X3�#�t�D!�g�4�o�,�L���i�I�D6wC��j�B?��FQ��3��/^\͍N<Ⱥ�B���Ƭ*�t��s87�g��as���Z�5�U�#AD�Z������2����NTyE����af�Rz�ͳ���B.�1�$fڍ�����j4��C�f���V+L�-f��iD�G��2�Q�U��S�&X�P����rxܪ&�`���O��Zk�*�+�YI�{�2�����8
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Services/TenantContext.cs:
--------------------------------------------------------------------------------
1 | using System.Web;
2 | using SharpArchitecture.MultiTenant.Framework.Services;
3 |
4 | namespace SharpArchitecture.MultiTenant.Web.Services
5 | {
6 | public class TenantContext : ITenantContext
7 | {
8 | private const string DefaultStorageKey = "csr-tenant-context-key";
9 |
10 | public string Key
11 | {
12 | get
13 | {
14 | if (string.IsNullOrEmpty(StoredKey)) {
15 | StoredKey = KeyFromRequest;
16 | }
17 | return StoredKey;
18 | }
19 |
20 | set { StoredKey = value; }
21 | }
22 |
23 | public string KeyFromRequest
24 | {
25 | get
26 | {
27 | var host = HttpContext.Current.Request.Headers["HOST"];
28 | var domains = host.Split('.');
29 | return domains.Length >= 3 ? domains[0] : string.Empty;
30 | }
31 | }
32 |
33 | protected string StoredKey
34 | {
35 | get { return HttpContext.Current.Items[DefaultStorageKey] as string; }
36 | set { HttpContext.Current.Items[DefaultStorageKey] = value; }
37 | }
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/TempDataExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Web.Mvc;
2 |
3 | namespace SharpArchitecture.MultiTenant.Web.Controllers
4 | {
5 | ///
6 | /// Extension methods for TempDataDictionary
7 | ///
8 | public static class TempDataExtensions
9 | {
10 | ///
11 | /// Adds an object to the dictionary using the type name as the key
12 | ///
13 | ///
14 | /// The temp data.
15 | ///
16 | ///
17 | /// The obj to add.
18 | ///
19 | public static void SafeAdd(this TempDataDictionary tempData, object obj)
20 | {
21 | tempData.Add(obj.GetType().Name, obj);
22 | }
23 |
24 | ///
25 | /// Gets an object from the dictionary using the type name as the key
26 | ///
27 | ///
28 | /// The temp data.
29 | ///
30 | ///
31 | /// The object type
32 | ///
33 | ///
34 | /// The object
35 | ///
36 | public static T SafeGet(this TempDataDictionary tempData)
37 | {
38 | object obj;
39 |
40 | if (tempData.TryGetValue(typeof(T).Name, out obj))
41 | {
42 | return (T)obj;
43 | }
44 |
45 | return default(T);
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Views/Customers/Create.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
2 | <%@ Import Namespace="SharpArchitecture.MultiTenant.Web.Controllers.Customers" %>
3 |
4 |
5 | New Customer
6 |
7 | <% using (Html.BeginForm()) {%>
8 |
9 | <%= Html.AntiForgeryToken() %>
10 |
11 |
12 | <%= Html.LabelFor(x => x.Code) %>
13 | <%= Html.TextBoxFor(x => x.Code)%>
14 | <%= Html.ValidationMessageFor(x => x.Code, "*")%>
15 |
16 |
17 | <%= Html.LabelFor(x => x.Name) %>
18 | <%= Html.TextBoxFor(x => x.Name)%>
19 | <%= Html.ValidationMessageFor(x => x.Name, "*")%>
20 |
21 |
22 | <%= Html.SubmitButton("submit", "Create") %> or <%= Html.ActionLink(c => c.Index(null), "Cancel")%>
23 |
24 |
25 |
26 | <% } %>
27 |
28 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Views/Customers/Delete.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
2 | <%@ Import Namespace="SharpArchitecture.MultiTenant.Web.Controllers.Customers" %>
3 |
4 |
5 | Delete Customer
6 |
7 | <% using (Html.BeginForm()) {%>
8 |
9 | <%= Html.AntiForgeryToken() %>
10 |
11 |
12 | <%= Html.LabelFor(x => x.Code) %>
13 | <%= Html.TextBoxFor(x => x.Code)%>
14 | <%= Html.ValidationMessageFor(x => x.Code, "*")%>
15 |
16 |
17 | <%= Html.LabelFor(x => x.Name) %>
18 | <%= Html.TextBoxFor(x => x.Name)%>
19 | <%= Html.ValidationMessageFor(x => x.Name, "*")%>
20 |
21 |
22 | <%= Html.SubmitButton("submit", "Delete") %>
23 | or <%= Html.ActionLink(c => c.Index(null), "Cancel")%>
24 |
25 |
26 |
27 | <% } %>
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Views/Customers/Edit.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
2 | <%@ Import Namespace="SharpArchitecture.MultiTenant.Web.Controllers.Customers" %>
3 |
4 |
5 | Edit Customer
6 |
7 | <% using (Html.BeginForm()) {%>
8 |
9 | <%= Html.AntiForgeryToken() %>
10 |
11 |
12 | <%= Html.LabelFor(x => x.Code) %>
13 | <%= Html.TextBoxFor(x => x.Code)%>
14 | <%= Html.ValidationMessageFor(x => x.Code, "*")%>
15 |
16 |
17 | <%= Html.LabelFor(x => x.Name) %>
18 | <%= Html.TextBoxFor(x => x.Name)%>
19 | <%= Html.ValidationMessageFor(x => x.Name, "*")%>
20 |
21 |
22 | <%= Html.SubmitButton("submit", "Update") %>
23 | or <%= Html.ActionLink(c => c.Index(null), "Cancel")%>
24 |
25 |
26 |
27 | <% } %>
28 |
29 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Views/Customers/Import.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
2 | <%@ Import Namespace="SharpArchitecture.MultiTenant.Web.Controllers.Customers" %>
3 |
4 |
5 | Import Customers
6 |
7 |
8 |
The data is being imported.
9 |
Please wait...
10 |
11 |
12 |
13 | <% using (Html.BeginForm()) {%>
14 |
15 | <%= Html.AntiForgeryToken() %>
16 | <%= Html.HiddenFor(m => m.UploadKey) %>
17 |
29 |
30 | <% } %>
31 |
32 |
33 |
60 |
61 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Views/Customers/Index.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage"%>
2 | <%@ Import Namespace="MvcContrib.UI.Pager" %>
3 | <%@ Import Namespace="MvcContrib.UI.Grid" %>
4 | <%@ Import Namespace="SharpArchitecture.MultiTenant.Web.Controllers.Customers" %>
5 |
6 |
7 | List of Customers
8 |
9 | <%= Html.ActionLink(x => x.Create(), "New Customer", new { @class="medium button" }) %>
10 | <%= Html.ActionLink(x => x.Import(), "Import Customers", new { @class="medium button" }) %>
11 |
12 | <%= Html.Grid(Model.Customers)
13 | .Columns(column =>
14 | {
15 | column.For(c => c.Code);
16 | column.For(c => c.Name);
17 | column.For(c => Html.ActionLink(x => x.Edit(c.Id), "edit"));
18 | column.For(c => Html.ActionLink(x => x.Delete(c.Id), "delete"));
19 | })
20 | %>
21 | <%= Html.Pager(Model.Customers)%>
22 |
23 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Views/Home/Index.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true"
2 | Inherits="System.Web.Mvc.ViewPage" %>
3 | <%@ Import Namespace="SharpArchitecture.MultiTenant.Web.Controllers" %>
4 |
5 |
6 | S#arp Architecture Project
7 |
8 | What next?
9 |
10 | Your S#arp Architecture 1.5 project is now setup and ready to go. This release is built on the RTM verion of ASP.NET MVC 2. The only tasks remaining
11 | are to:
12 |
13 |
14 | Create your database and set the connection string
15 | within SharpArchitecture.MultiTenant.Web/NHibernate.config
16 |
17 |
18 | Optionally, modify the Fluent NHibernate preferences within SharpArchitecture.MultiTenant.Data.NHibernateMaps.GetConventions()
19 | if you don't like the default settings. There's lots of terrific info about Fluent NHibernate
20 | at http://wiki.fluentnhibernate.org/show/HomePage .
21 |
22 |
23 | Open SharpArchitecture.MultiTenant.Tests.dll via NUnit and make sure all the tests are turning green.
24 |
25 |
26 | Add your first entity with CRUD scaffolding via /Code Generation/CrudScaffolding/ScaffoldingGeneratorCommand.tt.
27 | (If you include a namespace, be sure to setup the appropriate view area within
28 | SharpArchitecture.MultiTenant.Web.Controllers.RouteRegistrar.RegisterRoutesTo() after the scaffolding generator has completed.)
29 |
30 |
31 |
32 |
33 | If you need direction on what to do next, take a look at the documentation found in the
34 | /docs folder of the S#arp Architecture release package which provides a solid tutorial.
35 | You can also ask for assitance and guidance on the
36 | S#arp Architecture discussion boards .
37 |
38 |
39 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Views/Shared/DebugFormSubmission.ascx:
--------------------------------------------------------------------------------
1 | <%@ Control Language="C#" AutoEventWireup="true" Inherits="System.Web.Mvc.ViewUserControl" %>
2 |
3 |
4 | ModelState
5 |
6 |
7 |
8 |
9 | Key
10 | Attempted Value (for display purposes)
11 | Raw Value
12 | Error Count
13 | Error 1 Message
14 |
15 |
16 |
17 | <% foreach (string key in ViewData.ModelState.Keys) { %>
18 |
19 | <%= key %>
20 | <%= ViewData.ModelState[key].Value.AttemptedValue %>
21 | <%= ViewData.ModelState[key].Value.RawValue %>
22 | <%= ViewData.ModelState[key].Errors.Count %>
23 |
24 | <% if (ViewData.ModelState[key].Errors.Count > 0) {
25 | for (int i=0; i < ViewData.ModelState[key].Errors.Count; i++) {
26 | Response.Write("Error " + i + ": " + ViewData.ModelState[key].Errors[i].ErrorMessage +
27 | "; Exception = " +
28 | (ViewData.ModelState[key].Errors[i].Exception == null
29 | ? "N/A"
30 | : ViewData.ModelState[key].Errors[i].Exception.GetType().ToString() + (ViewData.ModelState[key].Errors[i].Exception.InnerException == null
31 | ? " (with no inner exception)"
32 | : ViewData.ModelState[key].Errors[i].Exception.InnerException.GetType().ToString())) + " ");
33 | }
34 | } %>
35 |
36 |
37 | <% } %>
38 |
39 |
40 |
41 |
42 |
43 | Request.Form Elements
44 | <%= Request.Form.ToString().Replace("&", " ")%>
45 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Views/Shared/Error.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true"
2 | Inherits="System.Web.Mvc.ViewPage" %>
3 |
4 |
5 |
6 | OMG, What have you done??? You broke the application...YOU broke it!!!
7 |
8 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Views/Shared/Site.Master:
--------------------------------------------------------------------------------
1 | <%@ Master Language="C#" AutoEventWireup="true"
2 | Inherits="System.Web.Mvc.ViewMasterPage" %>
3 | <%@ Import Namespace="SharpArchitecture.MultiTenant.Web.Controllers" %>
4 | <%@ Import Namespace="SharpArchitecture.MultiTenant.Web.Controllers.Customers" %>
5 | <%@ Import Namespace="SharpArchitecture.MultiTenant.Web.Controllers.Tenants" %>
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | Content/Site.css" rel="stylesheet" type="text/css" />
14 |
15 |
16 |
17 |
18 | <% // At bottom to facilitate other JS files to be loaded before page-by-page JS is loaded %>
19 |
20 | SharpArchitecture.MultiTenant
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | <%= Html.Image("~/Content/Images/sharp_arch.jpg") %>
34 |
35 |
SharpArchitecture.MultiTenant Pages
36 |
43 |
44 |
45 |
46 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
<%= Html.Image("~/Content/Images/sharp_arch_small.gif")%>
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Views/Tenants/Create.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
2 | <%@ Import Namespace="SharpArchitecture.MultiTenant.Web.Controllers.Tenants" %>
3 |
4 |
5 | New Tenant
6 |
7 | <% using (Html.BeginForm()) {%>
8 |
9 | <%= Html.AntiForgeryToken() %>
10 |
11 |
12 | <%= Html.LabelFor(x => x.Name) %>
13 | <%= Html.TextBoxFor(x => x.Name)%>
14 | <%= Html.ValidationMessageFor(x => x.Name, "*")%>
15 |
16 |
17 | <%= Html.LabelFor(x => x.Domain) %>
18 | <%= Html.TextBoxFor(x => x.Domain)%>
19 | <%= Html.ValidationMessageFor(x => x.Domain, "*")%>
20 |
21 |
22 | <%= Html.LabelFor(x => x.ConnectionString) %>
23 | <%= Html.TextBoxFor(x => x.ConnectionString)%>
24 | <%= Html.ValidationMessageFor(x => x.ConnectionString, "*")%>
25 |
26 |
27 | <%= Html.SubmitButton("submit", "Create") %> or <%= Html.ActionLink(c => c.Index(null), "Cancel")%>
28 |
29 |
30 |
31 | <% } %>
32 |
33 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Views/Tenants/Delete.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
2 | <%@ Import Namespace="SharpArchitecture.MultiTenant.Web.Controllers.Tenants" %>
3 |
4 |
5 | Delete Tenant
6 |
7 | <% using (Html.BeginForm()) {%>
8 |
9 | <%= Html.AntiForgeryToken() %>
10 |
11 |
12 | <%= Html.LabelFor(x => x.Name) %>
13 | <%= Html.TextBoxFor(x => x.Name)%>
14 | <%= Html.ValidationMessageFor(x => x.Name, "*")%>
15 |
16 |
17 | <%= Html.LabelFor(x => x.Domain) %>
18 | <%= Html.TextBoxFor(x => x.Domain)%>
19 | <%= Html.ValidationMessageFor(x => x.Domain, "*")%>
20 |
21 |
22 | <%= Html.LabelFor(x => x.ConnectionString) %>
23 | <%= Html.TextBoxFor(x => x.ConnectionString)%>
24 | <%= Html.ValidationMessageFor(x => x.ConnectionString, "*")%>
25 |
26 |
27 | <%= Html.SubmitButton("submit", "Delete") %>
28 | or <%= Html.ActionLink(c => c.Index(null), "Cancel")%>
29 |
30 |
31 |
32 | <% } %>
33 |
34 |
35 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Views/Tenants/Edit.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
2 | <%@ Import Namespace="SharpArchitecture.MultiTenant.Web.Controllers.Tenants" %>
3 |
4 |
5 | Edit Tenant
6 |
7 | <% using (Html.BeginForm()) {%>
8 |
9 | <%= Html.AntiForgeryToken() %>
10 |
11 |
12 | <%= Html.LabelFor(x => x.Name) %>
13 | <%= Html.TextBoxFor(x => x.Name)%>
14 | <%= Html.ValidationMessageFor(x => x.Name, "*")%>
15 |
16 |
17 | <%= Html.LabelFor(x => x.Domain) %>
18 | <%= Html.TextBoxFor(x => x.Domain)%>
19 | <%= Html.ValidationMessageFor(x => x.Domain, "*")%>
20 |
21 |
22 | <%= Html.LabelFor(x => x.ConnectionString) %>
23 | <%= Html.TextBoxFor(x => x.ConnectionString)%>
24 | <%= Html.ValidationMessageFor(x => x.ConnectionString, "*")%>
25 |
26 |
27 | <%= Html.SubmitButton("submit", "Update") %>
28 | or <%= Html.ActionLink(c => c.Index(null), "Cancel")%>
29 |
30 |
31 |
32 | <% } %>
33 |
34 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Views/Tenants/Index.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage"%>
2 | <%@ Import Namespace="MvcContrib.UI.Pager" %>
3 | <%@ Import Namespace="MvcContrib.UI.Grid" %>
4 | <%@ Import Namespace="SharpArchitecture.MultiTenant.Web.Controllers.Tenants" %>
5 |
6 |
7 | List of Tenants
8 |
9 | <%= Html.ActionLink(x => x.Create(), "New Tenant", new { @class = "medium button" })%>
10 |
11 | <%= Html.Grid(Model.Tenants)
12 | .Columns(column =>
13 | {
14 | column.For(c => c.Name);
15 | column.For(c => c.Domain);
16 | column.For(c => c.ConnectionString);
17 | column.For(c => Html.ActionLink(x => x.Edit(c.Id), "edit"));
18 | column.For(c => Html.ActionLink(x => x.Delete(c.Id), "delete"));
19 | })
20 | %>
21 | <%= Html.Pager(Model.Tenants)%>
22 |
23 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Views/Web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
9 |
16 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/app/SharpArchitecture-MultiTenant.Web/Web.config:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/db/schema/UnitTestGeneratedSchema.sql:
--------------------------------------------------------------------------------
1 |
2 | if exists (select * from dbo.sysobjects where id = object_id(N'Tenants') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table Tenants
3 |
4 | if exists (select * from dbo.sysobjects where id = object_id(N'hibernate_unique_key') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table hibernate_unique_key
5 |
6 | create table Tenants (
7 | Id INT not null,
8 | Name NVARCHAR(255) null,
9 | Domain NVARCHAR(255) null,
10 | ConnectionString NVARCHAR(255) null,
11 | primary key (Id)
12 | )
13 |
14 | create table hibernate_unique_key (
15 | next_hi INT
16 | )
17 |
18 | insert into hibernate_unique_key values ( 1 )
19 |
--------------------------------------------------------------------------------
/lib/Antlr3.Runtime.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/Antlr3.Runtime.dll
--------------------------------------------------------------------------------
/lib/Castle.Core.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/Castle.Core.dll
--------------------------------------------------------------------------------
/lib/Castle.Services.Logging.Log4netIntegration.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/Castle.Services.Logging.Log4netIntegration.dll
--------------------------------------------------------------------------------
/lib/Castle.Services.Transaction.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/Castle.Services.Transaction.dll
--------------------------------------------------------------------------------
/lib/Castle.Windsor.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/Castle.Windsor.dll
--------------------------------------------------------------------------------
/lib/CommonServiceLocator.WindsorAdapter.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/CommonServiceLocator.WindsorAdapter.dll
--------------------------------------------------------------------------------
/lib/FluentNHibernate.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/FluentNHibernate.dll
--------------------------------------------------------------------------------
/lib/Gallio.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/Gallio.dll
--------------------------------------------------------------------------------
/lib/Iesi.Collections.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/Iesi.Collections.dll
--------------------------------------------------------------------------------
/lib/Inflector.Net.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/Inflector.Net.dll
--------------------------------------------------------------------------------
/lib/MbUnit.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/MbUnit.dll
--------------------------------------------------------------------------------
/lib/Microsoft.Practices.ServiceLocation.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/Microsoft.Practices.ServiceLocation.dll
--------------------------------------------------------------------------------
/lib/Microsoft.Web.Mvc.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/Microsoft.Web.Mvc.dll
--------------------------------------------------------------------------------
/lib/MvcContrib.FluentHtml.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/MvcContrib.FluentHtml.dll
--------------------------------------------------------------------------------
/lib/MvcContrib.TestHelper.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/MvcContrib.TestHelper.dll
--------------------------------------------------------------------------------
/lib/MvcContrib.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/MvcContrib.dll
--------------------------------------------------------------------------------
/lib/NHibernate.ByteCode.Castle.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/NHibernate.ByteCode.Castle.dll
--------------------------------------------------------------------------------
/lib/NHibernate.Validator.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/NHibernate.Validator.dll
--------------------------------------------------------------------------------
/lib/NHibernate.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/NHibernate.dll
--------------------------------------------------------------------------------
/lib/Newtonsoft.Json.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/Newtonsoft.Json.dll
--------------------------------------------------------------------------------
/lib/Remotion.Data.Linq.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/Remotion.Data.Linq.dll
--------------------------------------------------------------------------------
/lib/Rhino.Mocks.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/Rhino.Mocks.dll
--------------------------------------------------------------------------------
/lib/SharpArch.Domain.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/SharpArch.Domain.dll
--------------------------------------------------------------------------------
/lib/SharpArch.NHibernate.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/SharpArch.NHibernate.dll
--------------------------------------------------------------------------------
/lib/SharpArch.Testing.NUnit.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/SharpArch.Testing.NUnit.dll
--------------------------------------------------------------------------------
/lib/SharpArch.Testing.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/SharpArch.Testing.dll
--------------------------------------------------------------------------------
/lib/SharpArch.Tests.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/SharpArch.Tests.dll
--------------------------------------------------------------------------------
/lib/SharpArch.Wcf.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/SharpArch.Wcf.dll
--------------------------------------------------------------------------------
/lib/SharpArch.Web.Mvc.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/SharpArch.Web.Mvc.dll
--------------------------------------------------------------------------------
/lib/System.Data.SQLite.DLL:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/System.Data.SQLite.DLL
--------------------------------------------------------------------------------
/lib/System.Web.Abstractions.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/System.Web.Abstractions.dll
--------------------------------------------------------------------------------
/lib/System.Web.Mvc.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/System.Web.Mvc.dll
--------------------------------------------------------------------------------
/lib/System.Web.Routing.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/System.Web.Routing.dll
--------------------------------------------------------------------------------
/lib/log4net.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/log4net.dll
--------------------------------------------------------------------------------
/lib/nunit.framework.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/lib/nunit.framework.dll
--------------------------------------------------------------------------------
/logs/SharpArchitecture-MultiTenant.Web.log:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/SharpArchitecture-MultiTenant.Tests/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/tests/SharpArchitecture-MultiTenant.Tests/Hibernate.cfg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | NHibernate.Connection.DriverConnectionProvider
5 | NHibernate.Dialect.SQLiteDialect
6 | NHibernate.Driver.SQLite20Driver
7 | Data Source=:memory:;Version=3;New=True;
8 | on_close
9 | true
10 | NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle
11 |
12 |
--------------------------------------------------------------------------------
/tests/SharpArchitecture-MultiTenant.Tests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("SharpArchitecture.MultiTenant.Tests")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyProduct("SharpArchitecture.MultiTenant.Tests")]
11 |
12 | // The following GUID is for the ID of the typelib if this project is exposed to COM
13 | [assembly: Guid("ead38380-798c-4387-bfaf-861734839177")]
14 |
--------------------------------------------------------------------------------
/tests/SharpArchitecture-MultiTenant.Tests/ServiceLocatorInitializer.cs:
--------------------------------------------------------------------------------
1 | using Castle.Windsor;
2 | using CommonServiceLocator.WindsorAdapter;
3 | using Microsoft.Practices.ServiceLocation;
4 | using SharpArch.Domain.PersistenceSupport;
5 | using Tests.SharpArchitecture.MultiTenant.Data.TestDoubles;
6 |
7 | namespace Tests
8 | {
9 | using Castle.MicroKernel.Registration;
10 |
11 | public class ServiceLocatorInitializer
12 | {
13 | public static void Init()
14 | {
15 | IWindsorContainer container = new WindsorContainer();
16 |
17 | container.Register(
18 | Component
19 | .For(typeof(IEntityDuplicateChecker))
20 | .ImplementedBy(typeof(EntityDuplicateCheckerStub))
21 | .Named("entityDuplicateChecker"));
22 |
23 | ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(container));
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tests/SharpArchitecture-MultiTenant.Tests/SharpArchitecture.MultiTenant.Data/NHibernateMaps/MappingIntegrationTests.cs:
--------------------------------------------------------------------------------
1 | using NHibernate;
2 | using NHibernate.Cfg;
3 | using NHibernate.Tool.hbm2ddl;
4 | using NUnit.Framework;
5 | using SharpArch.NHibernate;
6 | using SharpArchitecture.MultiTenant.Data.NHibernateMaps;
7 | using SharpArch.Testing.NHibernate;
8 | using System.IO;
9 |
10 | namespace Tests.SharpArchitecture.MultiTenant.Data.NHibernateMaps
11 | {
12 | ///
13 | /// Provides a means to verify that the target database is in compliance with all mappings.
14 | /// Taken from http://ayende.com/Blog/archive/2006/08/09/NHibernateMappingCreatingSanityChecks.aspx.
15 | ///
16 | /// If this is failing, the error will likely inform you that there is a missing table or column
17 | /// which needs to be added to your database.
18 | ///
19 | [TestFixture]
20 | [Category("DB Tests")]
21 | public class MappingIntegrationTests
22 | {
23 | [SetUp]
24 | public virtual void SetUp()
25 | {
26 | string[] mappingAssemblies = RepositoryTestsHelper.GetMappingAssemblies();
27 | configuration = NHibernateSession.Init(new SimpleSessionStorage(), mappingAssemblies,
28 | new AutoPersistenceModelGenerator().Generate(),
29 | "../../../../app/SharpArchitecture-MultiTenant.Web/NHibernate.config");
30 | }
31 |
32 | [TearDown]
33 | public virtual void TearDown()
34 | {
35 | NHibernateSession.CloseAllSessions();
36 | NHibernateSession.Reset();
37 | }
38 |
39 | [Test]
40 | public void CanConfirmDatabaseMatchesMappings()
41 | {
42 | var allClassMetadata = NHibernateSession.GetDefaultSessionFactory().GetAllClassMetadata();
43 |
44 | foreach (var entry in allClassMetadata)
45 | {
46 | NHibernateSession.Current.CreateCriteria(entry.Value.GetMappedClass(EntityMode.Poco))
47 | .SetMaxResults(0).List();
48 | }
49 | }
50 |
51 | ///
52 | /// Generates and outputs the database schema SQL to the console
53 | ///
54 | [Test]
55 | public void CanGenerateDatabaseSchema()
56 | {
57 | var session = NHibernateSession.GetDefaultSessionFactory().OpenSession();
58 |
59 | using (TextWriter stringWriter = new StreamWriter("../../../../db/schema/UnitTestGeneratedSchema.sql"))
60 | {
61 | new SchemaExport(configuration).Execute(true, false, false, session.Connection, stringWriter);
62 | }
63 | }
64 |
65 | private Configuration configuration;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/tests/SharpArchitecture-MultiTenant.Tests/SharpArchitecture.MultiTenant.Data/TestDoubles/EntityDuplicateCheckerStub.cs:
--------------------------------------------------------------------------------
1 | using SharpArch.Domain.DomainModel;
2 | using SharpArch.Domain.PersistenceSupport;
3 |
4 | namespace Tests.SharpArchitecture.MultiTenant.Data.TestDoubles
5 | {
6 | ///
7 | /// A test double for . The default implementation
8 | /// always assumes that a duplicate does not exist. This may be modified to acccount for
9 | /// different testing scenarios. This test double gets registered within
10 | /// .
11 | ///
12 | public class EntityDuplicateCheckerStub : IEntityDuplicateChecker
13 | {
14 | public bool DoesDuplicateExistWithTypedIdOf(IEntityWithTypedId entity)
15 | {
16 | return false;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tests/SharpArchitecture-MultiTenant.Tests/SharpArchitecture.MultiTenant.Framework/NHibernate/MultiTenantSessionFactoryKeyProviderTests.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 | using Rhino.Mocks;
3 | using SharpArch.Domain.DomainModel;
4 | using SharpArch.Domain.PersistenceSupport;
5 | using SharpArch.NHibernate;
6 | using SharpArch.Testing.NUnit;
7 | using SharpArchitecture.MultiTenant.Framework.Contracts;
8 | using SharpArchitecture.MultiTenant.Framework.NHibernate;
9 | using SharpArchitecture.MultiTenant.Framework.Services;
10 |
11 | namespace Tests.SharpArchitecture.MultiTenant.Framework.NHibernate
12 | {
13 | public class TestEntity : Entity {}
14 | public class TestMultiTenantEntity : Entity, IMultiTenantEntity {}
15 |
16 | public interface ITestRepository : IRepository { }
17 | public interface ITestMultiTenantRepository : IRepository, IMultiTenantRepository { }
18 |
19 | public class TestRepository : NHibernateRepository, ITestRepository { }
20 | public class TestMultiTenantRepository : NHibernateRepository, ITestMultiTenantRepository { }
21 |
22 | [TestFixture]
23 | public class MultiTenantSessionFactoryKeyProviderTests
24 | {
25 | private MultiTenantSessionFactoryKeyProvider _provider;
26 |
27 | [SetUp]
28 | public void Setup()
29 | {
30 | var tenantContext = MockRepository.GenerateStub();
31 | _provider = new MultiTenantSessionFactoryKeyProvider(tenantContext);
32 | }
33 |
34 | [Test]
35 | public void IsRepositoryForMultiTenantEntityReturnsFlaseForRepositoryForEntity()
36 | {
37 | var isRepositoryForMultiTenantEntity = _provider.IsRepositoryForMultiTenantEntity(typeof(IRepository));
38 | isRepositoryForMultiTenantEntity.ShouldEqual(false);
39 | }
40 |
41 | [Test]
42 | public void IsRepositoryForMultiTenantEntityReturnsTrueForRepositoryForMultiTenantEntity()
43 | {
44 | var isRepositoryForMultiTenantEntity = _provider.IsRepositoryForMultiTenantEntity(typeof(IRepository));
45 | isRepositoryForMultiTenantEntity.ShouldEqual(true);
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/tests/SharpArchitecture-MultiTenant.Tests/SharpArchitecture.MultiTenant.Web/Controllers/RouteRegistrarTests.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 | using SharpArchitecture.MultiTenant.Web.Controllers;
3 | using MvcContrib.TestHelper;
4 | using System.Web.Routing;
5 |
6 | namespace Tests.SharpArchitecture.MultiTenant.Controllers
7 | {
8 | [TestFixture]
9 | public class RouteRegistrarTests
10 | {
11 | [SetUp]
12 | public void SetUp()
13 | {
14 | RouteTable.Routes.Clear();
15 | RouteRegistrar.RegisterRoutesTo(RouteTable.Routes);
16 | }
17 |
18 | [Test]
19 | public void CanVerifyRouteMaps()
20 | {
21 | "~/".Route().ShouldMapTo(x => x.Index());
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/tools/CrudScaffolding/CrudScaffolding.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 |
7 |
8 | 2.0
9 | {BC94CA49-93AB-45AE-909C-213B4DC8498B}
10 | Library
11 | Properties
12 | SharpArch.Scaffolding
13 | SharpArch.Scaffolding
14 | v3.5
15 | 512
16 |
17 |
18 |
19 |
20 | 3.5
21 |
22 |
23 | true
24 | full
25 | false
26 | bin\Debug\
27 | DEBUG;TRACE
28 | prompt
29 | 4
30 | AllRules.ruleset
31 |
32 |
33 | pdbonly
34 | true
35 | bin\Release\
36 | TRACE
37 | prompt
38 | 4
39 | AllRules.ruleset
40 |
41 |
42 |
43 | False
44 | C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies\EnvDTE.dll
45 |
46 |
47 | False
48 | ..\..\lib\Inflector.Net.dll
49 |
50 |
51 | ..\..\lib\SharpArch.dll
52 |
53 |
54 |
55 | 3.5
56 |
57 |
58 | 3.5
59 |
60 |
61 | 3.5
62 |
63 |
64 |
65 |
66 |
67 |
68 | Properties\CommonAssemblyInfo.cs
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | TextTemplatingFileGenerator
77 | ScaffoldingGeneratorCommand.txt
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | True
110 | True
111 | ScaffoldingGeneratorCommand.tt
112 |
113 |
114 |
115 |
122 |
--------------------------------------------------------------------------------
/tools/CrudScaffolding/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("CrudScaffolding")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyProduct("CrudScaffolding")]
11 |
12 | // The following GUID is for the ID of the typelib if this project is exposed to COM
13 | [assembly: Guid("88814273-41cc-4e65-92f3-0ed35893628d")]
14 |
--------------------------------------------------------------------------------
/tools/CrudScaffolding/ScaffoldingGeneratorCommand.tt:
--------------------------------------------------------------------------------
1 | <#@ template language="C#" hostspecific="True" debug="True" #>
2 | <#@ import namespace="System.Collections.Specialized" #>
3 | <#@ output extension="txt" #>
4 | <#@ include file="T4Toolbox.tt" #>
5 | <#@ include file="./Templates/ScaffoldingGenerator.tt" #>
6 | <#@ include file="EntityScaffoldingDetails.tt" #>
7 |
8 | <#
9 | ///////////////////////////////////////////////////
10 | // Set your domain object details below and simply uncomment the last line (".Run()") and save this file to auto-generate the scaffolding
11 |
12 | /*
13 | * Domain name should be PascalCaseSingular with no spaces.
14 | * You may qualify the domain object with a namespace; a folder structure reflecting the namespace structure will be created (or verified).
15 | * A log of created artifacts may be found in /SharpArchitecture.MultiTenant/logs/CrudScaffolding.log
16 | * Examples: Product, Organization.Employee, Financial.Costs.LedgerEntry
17 | */
18 | EntityScaffoldingDetails entityScaffoldingDetails =
19 | new EntityScaffoldingDetails("Organization.Worker");
20 |
21 | /*
22 | * Property names should be PascalCase.
23 | * Do not include a property for Id as it will be included automatically.
24 | */
25 | entityScaffoldingDetails.EntityProperties.Add(
26 | new EntityProperty("FirstName", "string", "Joe", "[NotNull, NotEmpty]", true)
27 | );
28 | entityScaffoldingDetails.EntityProperties.Add(
29 | new EntityProperty("LastName", "string", "Smith", "[NotNull, NotEmpty]", true)
30 | );
31 | entityScaffoldingDetails.EntityProperties.Add(
32 | new EntityProperty("BirthDate", "DateTime", DateTime.Parse("1/1/1975"))
33 | );
34 | entityScaffoldingDetails.EntityProperties.Add(
35 | new EntityProperty("Manager", "Employee", null, "[NotNull]")
36 | );
37 |
38 | ///////////////////////////////////////////////////
39 |
40 | // The first parameter should reflect the root directory of your solution
41 | ScaffoldingGenerator generator = new ScaffoldingGenerator(
42 | @"C:\Projects\SharpArchitecture.MultiTenant\", "SharpArchitecture.MultiTenant", entityScaffoldingDetails);
43 |
44 | // Uncomment this line when you're ready for the scaffolding generator to fire...be sure to recomment after it completes to avoid accidental generating!
45 | //generator.Run();
46 | #>
--------------------------------------------------------------------------------
/tools/CrudScaffolding/ScaffoldingGeneratorCommand.txt:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/tools/CrudScaffolding/Templates/BaseTemplate.tt:
--------------------------------------------------------------------------------
1 | <#@ assembly name="$(SolutionDir)lib\Inflector.Net.dll" #>
2 |
3 | <#+
4 | public abstract class BaseTemplate : Template
5 | {
6 | public BaseTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails) {
7 | this.solutionName = solutionName;
8 | this.entityScaffoldingDetails = entityScaffoldingDetails;
9 | }
10 |
11 | protected string SolutionName {
12 | get { return solutionName; }
13 | }
14 |
15 | protected EntityScaffoldingDetails EntityScaffoldingDetails {
16 | get { return entityScaffoldingDetails; }
17 | }
18 |
19 | protected string AppendNamespaceHierarchyTo(string namespacePath) {
20 | if (entityScaffoldingDetails.NamespaceHierarchy == null ||
21 | entityScaffoldingDetails.NamespaceHierarchy.Length == 0)
22 | return namespacePath;
23 |
24 | foreach (string namespaceToAppend in entityScaffoldingDetails.NamespaceHierarchy) {
25 | namespacePath += "." + namespaceToAppend;
26 | }
27 |
28 | return namespacePath;
29 | }
30 |
31 | protected string EntityBaseUrl {
32 | get {
33 | return ((entityScaffoldingDetails.NamespaceHierarchy != null && entityScaffoldingDetails.NamespaceHierarchy.Length > 0)
34 | ? (AppendNamespaceHierarchyTo("").Substring(1).Replace(".", "/") + "/")
35 | : "") +
36 | entityScaffoldingDetails.EntityNamePlural + "/";
37 | }
38 | }
39 |
40 | private readonly string solutionName;
41 | private readonly EntityScaffoldingDetails entityScaffoldingDetails;
42 | }
43 | #>
44 |
--------------------------------------------------------------------------------
/tools/CrudScaffolding/Templates/Core/DomainObjectTemplate.tt:
--------------------------------------------------------------------------------
1 | <#@ import namespace="System.Collections" #>
2 |
3 | <#+
4 | public class DomainObjectTemplate : BaseTemplate
5 | {
6 | public DomainObjectTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
7 | : base(solutionName, entityScaffoldingDetails) { }
8 |
9 | public override string TransformText()
10 | {
11 | #>
12 | using NHibernate.Validator.Constraints;
13 | using SharpArch.Core.PersistenceSupport;
14 | using SharpArch.Core.DomainModel;
15 | using System;
16 |
17 | namespace <#= AppendNamespaceHierarchyTo(SolutionName + ".Core") #>
18 | {
19 | public class <#= EntityScaffoldingDetails.EntityName #> : Entity
20 | {
21 | public <#= EntityScaffoldingDetails.EntityName #>() { }
22 | <#+
23 | PushIndent("\t\t");
24 |
25 | foreach (EntityProperty property in EntityScaffoldingDetails.EntityProperties) {
26 | WriteLine("");
27 |
28 | if (property.IsPartOfDomainSignature)
29 | WriteLine("[DomainSignature]");
30 |
31 | if (! string.IsNullOrEmpty(property.PropertyAttributes))
32 | WriteLine(property.PropertyAttributes);
33 |
34 | WriteLine("public virtual " + property.TypeName + " " + property.PropertyName + " { get; set; }");
35 | }
36 |
37 | PopIndent();
38 | #>
39 | }
40 | }
41 | <#+ return this.GenerationEnvironment.ToString();
42 | }
43 | }
44 | #>
45 |
--------------------------------------------------------------------------------
/tools/CrudScaffolding/Templates/Tests/Core/DomainObjectTestsTemplate.tt:
--------------------------------------------------------------------------------
1 | <#+
2 | public class DomainObjectTestsTemplate : BaseTemplate
3 | {
4 | public DomainObjectTestsTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
5 | : base(solutionName, entityScaffoldingDetails) { }
6 |
7 | public override string TransformText()
8 | {
9 | #>
10 | using NUnit.Framework;
11 | using <#= AppendNamespaceHierarchyTo(SolutionName + ".Core") #>;
12 | using SharpArch.Testing;
13 | using SharpArch.Testing.NUnit;
14 |
15 | namespace <#= AppendNamespaceHierarchyTo("Tests." + SolutionName + ".Core") #>
16 | {
17 | <#+
18 | if (! EntityScaffoldingDetails.HasAnyDomainSignatureProperties) { #>
19 | ///
20 | /// A <#= EntityScaffoldingDetails.EntityNameCamelCase #>'s ID property is the only property which is compared to
21 | /// another <#= EntityScaffoldingDetails.EntityNameCamelCase #>. I.e., it does not have any domain signature
22 | /// properties other than the Id itself.
23 | ///
24 | <#+
25 | }
26 | #>
27 | [TestFixture]
28 | public class <#= EntityScaffoldingDetails.EntityName #>Tests
29 | {
30 | [Test]
31 | public void CanCompare<#= EntityScaffoldingDetails.EntityNamePlural #>() {
32 | <#= EntityScaffoldingDetails.EntityName #> instance = new <#= EntityScaffoldingDetails.EntityName #>();
33 | <#+
34 | PushIndent("\t\t\t");
35 |
36 | if (EntityScaffoldingDetails.HasAnyDomainSignatureProperties) {
37 | foreach (EntityProperty property in EntityScaffoldingDetails.EntityProperties) {
38 | if (property.IsPartOfDomainSignature) {
39 | WriteLine("instance." + property.PropertyName + " = " + property.GetDefaultValueForTests() + ";");
40 | }
41 | }
42 | }
43 | else {
44 | WriteLine("EntityIdSetter.SetIdOf(instance, 1);");
45 | }
46 |
47 | PopIndent();
48 | #>
49 |
50 | <#= EntityScaffoldingDetails.EntityName #> instanceToCompareTo = new <#= EntityScaffoldingDetails.EntityName #>();
51 | <#+
52 | PushIndent("\t\t\t");
53 |
54 | if (EntityScaffoldingDetails.HasAnyDomainSignatureProperties) {
55 | foreach (EntityProperty property in EntityScaffoldingDetails.EntityProperties) {
56 | if (property.IsPartOfDomainSignature) {
57 | WriteLine("instanceToCompareTo." + property.PropertyName + " = " + property.GetDefaultValueForTests() + ";");
58 | }
59 | }
60 | }
61 | else {
62 | WriteLine("EntityIdSetter.SetIdOf(instanceToCompareTo, 1);");
63 | }
64 |
65 | PopIndent();
66 | #>
67 |
68 | instance.ShouldEqual(instanceToCompareTo);
69 | }
70 | }
71 | }
72 | <#+ return this.GenerationEnvironment.ToString();
73 | }
74 | }
75 | #>
76 |
--------------------------------------------------------------------------------
/tools/CrudScaffolding/Templates/Web/Controllers/AreaRegistrationTemplate.tt:
--------------------------------------------------------------------------------
1 | <#@ import namespace="System.Collections" #>
2 |
3 | <#+
4 | public class AreaRegistrationTemplate : BaseTemplate
5 | {
6 |
7 | public AreaRegistrationTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
8 | : base(solutionName, entityScaffoldingDetails) { }
9 |
10 | public override string TransformText()
11 | {
12 |
13 | #>
14 |
15 | namespace <#= AppendNamespaceHierarchyTo(SolutionName + ".Web.Controllers") #>
16 | {
17 |
18 | public class <#= AppendNamespaceHierarchyTo("").Replace(".", "/").Trim('/') #>AreaRegistration : System.Web.Mvc.AreaRegistration
19 | {
20 | public override string AreaName {
21 | get {
22 | return "<#= AppendNamespaceHierarchyTo("").Replace(".", "/").Trim('/') #>";
23 | }
24 | }
25 |
26 | public override void RegisterArea(System.Web.Mvc.AreaRegistrationContext context) {
27 | context.MapRoute(
28 | "<#= AppendNamespaceHierarchyTo("").Replace(".", "") #>_default",
29 | "<#= AppendNamespaceHierarchyTo("").Replace(".", "/").Trim('/') #>/{controller}/{action}/{id}",
30 | new { action = "Index", id = "" }
31 | );
32 | }
33 | }
34 |
35 | } <#+ return this.GenerationEnvironment.ToString();
36 |
37 | }
38 |
39 | }
40 | #>
41 |
42 |
--------------------------------------------------------------------------------
/tools/CrudScaffolding/Templates/Web/Views/CreateTemplate.tt:
--------------------------------------------------------------------------------
1 | <#+
2 | public class CreateTemplate : BaseTemplate
3 | {
4 | public CreateTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
5 | : base(solutionName, entityScaffoldingDetails) { }
6 |
7 | public override string TransformText()
8 | {
9 | #>
10 | <%@ Page Title="Create <#= EntityScaffoldingDetails.EntityName #>" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true"
11 | Inherits="System.Web.Mvc.ViewPage<<#= AppendNamespaceHierarchyTo(SolutionName + ".Web.Controllers") #>.<#= EntityScaffoldingDetails.EntityNamePlural #>Controller.<#= EntityScaffoldingDetails.EntityName #>FormViewModel>" %>
12 |
13 |
14 |
15 | Create <#= EntityScaffoldingDetails.EntityName #>
16 |
17 | <% Html.RenderPartial("<#= EntityScaffoldingDetails.EntityName #>Form", ViewData); %>
18 |
19 |
20 | <#+ return this.GenerationEnvironment.ToString();
21 | }
22 | }
23 | #>
24 |
--------------------------------------------------------------------------------
/tools/CrudScaffolding/Templates/Web/Views/DomainObjectFormTemplate.tt:
--------------------------------------------------------------------------------
1 | <#@ import namespace="System.Collections" #>
2 |
3 | <#+
4 | public class DomainObjectFormTemplate : BaseTemplate
5 | {
6 | public DomainObjectFormTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
7 | : base(solutionName, entityScaffoldingDetails) { }
8 |
9 | public override string TransformText()
10 | {
11 | #>
12 | <%@ Control Language="C#" AutoEventWireup="true"
13 | Inherits="System.Web.Mvc.ViewUserControl<<#= AppendNamespaceHierarchyTo(SolutionName + ".Web.Controllers") #>.<#= EntityScaffoldingDetails.EntityNamePlural #>Controller.<#= EntityScaffoldingDetails.EntityName #>FormViewModel>" %>
14 | <%@ Import Namespace="<#= AppendNamespaceHierarchyTo(SolutionName + ".Core") #>" %>
15 | <%@ Import Namespace="<#= SolutionName #>.Web.Controllers" %>
16 | <#+ if (EntityScaffoldingDetails.NamespaceHierarchy != null) {
17 | #><%@ Import Namespace="<#= AppendNamespaceHierarchyTo(SolutionName + ".Web.Controllers") #>" %><#+
18 | } #>
19 |
20 | <% if (ViewContext.TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] != null) { %>
21 | <%= ViewContext.TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()]%>
22 | <% } %>
23 |
24 | <%= Html.ValidationSummary() %>
25 |
26 | <% Html.EnableClientValidation(); %>
27 | <% using (Html.BeginForm()) { %>
28 | <%= Html.AntiForgeryToken() %>
29 | <%= Html.Hidden("<#= EntityScaffoldingDetails.EntityName #>.Id", (ViewData.Model.<#= EntityScaffoldingDetails.EntityName #> != null) ? ViewData.Model.<#= EntityScaffoldingDetails.EntityName #>.Id : 0)%>
30 |
31 |
49 | <% } %>
50 | <#+ return this.GenerationEnvironment.ToString();
51 | }
52 | }
53 | #>
54 |
--------------------------------------------------------------------------------
/tools/CrudScaffolding/Templates/Web/Views/EditTemplate.tt:
--------------------------------------------------------------------------------
1 | <#+
2 | public class EditTemplate : BaseTemplate
3 | {
4 | public EditTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
5 | : base(solutionName, entityScaffoldingDetails) { }
6 |
7 | public override string TransformText()
8 | {
9 | #>
10 | <%@ Page Title="Edit <#= EntityScaffoldingDetails.EntityName #>" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true"
11 | Inherits="System.Web.Mvc.ViewPage<<#= AppendNamespaceHierarchyTo(SolutionName + ".Web.Controllers") #>.<#= EntityScaffoldingDetails.EntityNamePlural #>Controller.<#= EntityScaffoldingDetails.EntityName #>FormViewModel>" %>
12 |
13 |
14 |
15 | Edit <#= EntityScaffoldingDetails.EntityName #>
16 |
17 | <% Html.RenderPartial("<#= EntityScaffoldingDetails.EntityName #>Form", ViewData); %>
18 |
19 |
20 | <#+ return this.GenerationEnvironment.ToString();
21 | }
22 | }
23 | #>
24 |
--------------------------------------------------------------------------------
/tools/CrudScaffolding/Templates/Web/Views/IndexTemplate.tt:
--------------------------------------------------------------------------------
1 | <#@ import namespace="System.Collections" #>
2 |
3 | <#+
4 | public class IndexTemplate : BaseTemplate
5 | {
6 | public IndexTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
7 | : base(solutionName, entityScaffoldingDetails) { }
8 |
9 | public override string TransformText()
10 | {
11 | #>
12 | <%@ Page Title="<#= EntityScaffoldingDetails.EntityNamePlural #>" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true"
13 | Inherits="System.Web.Mvc.ViewPage.<#= EntityScaffoldingDetails.EntityName #>>>" %>
14 | <%@ Import Namespace="<#= AppendNamespaceHierarchyTo(SolutionName + ".Core") #>" %>
15 | <%@ Import Namespace="<#= SolutionName #>.Web.Controllers" %>
16 | <#+ if (EntityScaffoldingDetails.NamespaceHierarchy != null) {
17 | #><%@ Import Namespace="<#= AppendNamespaceHierarchyTo(SolutionName + ".Web.Controllers") #>" %><#+
18 | } #>
19 |
20 |
21 | <#= EntityScaffoldingDetails.EntityNamePlural #>
22 |
23 | <% if (ViewContext.TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] != null) { %>
24 | <%= ViewContext.TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()]%>
25 | <% } %>
26 |
27 |
62 |
63 | <%= Html.ActionLink<<#= EntityScaffoldingDetails.EntityNamePlural #>Controller>(c => c.Create(), "Create New <#= EntityScaffoldingDetails.EntityName #>") %>
64 |
65 | <#+ return this.GenerationEnvironment.ToString();
66 | }
67 | }
68 | #>
69 |
--------------------------------------------------------------------------------
/tools/CrudScaffolding/Templates/Web/Views/ShowTemplate.tt:
--------------------------------------------------------------------------------
1 | <#@ import namespace="System.Collections" #>
2 |
3 | <#+
4 | public class ShowTemplate : BaseTemplate
5 | {
6 | public ShowTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
7 | : base(solutionName, entityScaffoldingDetails) { }
8 |
9 | public override string TransformText()
10 | {
11 | #>
12 | <%@ Page Title="<#= EntityScaffoldingDetails.EntityName #> Details" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true"
13 | Inherits="System.Web.Mvc.ViewPage<<#= AppendNamespaceHierarchyTo(SolutionName + ".Core") #>.<#= EntityScaffoldingDetails.EntityName #>>" %>
14 | <%@ Import Namespace="<#= AppendNamespaceHierarchyTo(SolutionName + ".Web.Controllers") #>" %>
15 |
16 |
17 |
18 | <#= EntityScaffoldingDetails.EntityName #> Details
19 |
20 |
21 | <#+
22 | foreach (EntityProperty property in EntityScaffoldingDetails.EntityProperties) {
23 | #>
24 |
25 | <#= property.PropertyName #>:
26 | <%= Server.HtmlEncode(ViewData.Model.<#= property.PropertyName #>.ToString()) %>
27 |
28 | <#+
29 | }
30 | #>
31 |
32 | <%= Html.Button("btnBack", "Back", HtmlButtonType.Button,
33 | "window.location.href = '" + Html.BuildUrlFromExpressionForAreas<<#= EntityScaffoldingDetails.EntityNamePlural #>Controller>(c => c.Index()) + "';") %>
34 |
35 |
36 |
37 |
38 | <#+ return this.GenerationEnvironment.ToString();
39 | }
40 | }
41 | #>
42 |
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/CrudScaffoldingForEnterpriseApp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 |
7 |
8 | 2.0
9 | {D0A5D52D-4397-4DD7-BD20-8FBE3C35288F}
10 | Library
11 | Properties
12 | SharpArch.Scaffolding
13 | SharpArch.Scaffolding
14 | v3.5
15 | 512
16 |
17 |
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 | False
37 | C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies\EnvDTE.dll
38 |
39 |
40 | False
41 | ..\..\lib\Inflector.Net.dll
42 |
43 |
44 | ..\..\lib\SharpArch.dll
45 |
46 |
47 |
48 | 3.5
49 |
50 |
51 | 3.5
52 |
53 |
54 | 3.5
55 |
56 |
57 |
58 |
59 |
60 |
61 | Properties\CommonAssemblyInfo.cs
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | TextTemplatingFileGenerator
70 | ScaffoldingGeneratorCommand.txt
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 | AreaRegistrationTemplate.cs
120 |
121 |
122 |
123 |
124 | True
125 | True
126 | ScaffoldingGeneratorCommand.tt
127 |
128 |
129 |
130 |
137 |
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("CrudScaffoldingForEnterpriseApp")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyProduct("CrudScaffoldingForEnterpriseApp")]
11 |
12 | // The following GUID is for the ID of the typelib if this project is exposed to COM
13 | [assembly: Guid("18b48ebc-5365-45fe-9812-4c59ac30d005")]
14 |
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/ScaffoldingGeneratorCommand.tt:
--------------------------------------------------------------------------------
1 | <#@ template language="C#" hostspecific="True" debug="True" #>
2 | <#@ import namespace="System.Collections.Specialized" #>
3 | <#@ output extension="txt" #>
4 | <#@ include file="T4Toolbox.tt" #>
5 | <#@ include file="./Templates/ScaffoldingGenerator.tt" #>
6 | <#@ include file="EntityScaffoldingDetails.tt" #>
7 |
8 | <#
9 | ///////////////////////////////////////////////////
10 | // Set your domain object details below and simply uncomment the last line (".Run()") and save this file to auto-generate the scaffolding
11 |
12 | /*
13 | * Domain name should be PascalCaseSingular with no spaces.
14 | * You may qualify the domain object with a namespace; a folder structure reflecting the namespace structure will be created (or verified).
15 | * A log of created artifacts may be found in /SharpArchitecture.MultiTenant/logs/CrudScaffolding.log
16 | * Examples: Product, Organization.Employee, Financial.Costs.LedgerEntry
17 | */
18 | EntityScaffoldingDetails entityScaffoldingDetails =
19 | new EntityScaffoldingDetails("Organization.Worker");
20 |
21 | /*
22 | * Property names should be PascalCase.
23 | * Do not include a property for Id as it will be included automatically.
24 | */
25 | entityScaffoldingDetails.EntityProperties.Add(
26 | new EntityProperty("FirstName", "string", "Joe", "[NotNull, NotEmpty]", true)
27 | );
28 | entityScaffoldingDetails.EntityProperties.Add(
29 | new EntityProperty("LastName", "string", "Smith", "[NotNull, NotEmpty]", true)
30 | );
31 | entityScaffoldingDetails.EntityProperties.Add(
32 | new EntityProperty("BirthDate", "DateTime", DateTime.Parse("1/1/1975"))
33 | );
34 | entityScaffoldingDetails.EntityProperties.Add(
35 | new EntityProperty("Manager", "Employee", null, "[NotNull]")
36 | );
37 |
38 | ///////////////////////////////////////////////////
39 |
40 | // The first parameter should reflect the root directory of your solution
41 | ScaffoldingGenerator generator = new ScaffoldingGenerator(
42 | @"C:\Projects\SharpArchitecture.MultiTenant\", "SharpArchitecture.MultiTenant", entityScaffoldingDetails);
43 |
44 | // Uncomment this line when you're ready for the scaffolding generator to fire...be sure to recomment after it completes to avoid accidental generating!
45 | //generator.Run();
46 | #>
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/ScaffoldingGeneratorCommand.txt:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/Templates/ApplicationServices/IDomainObjectManagementServiceTemplate.tt:
--------------------------------------------------------------------------------
1 | <#+
2 | public class IDomainObjectManagementServiceTemplate : BaseTemplate
3 | {
4 | public IDomainObjectManagementServiceTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
5 | : base(solutionName, entityScaffoldingDetails) { }
6 |
7 | public override string TransformText()
8 | {
9 | #>
10 | using System.Collections.Generic;
11 | using <#= AppendNamespaceHierarchyTo(SolutionName + ".Core") #>;
12 | using <#= AppendNamespaceHierarchyTo(SolutionName + ".ApplicationServices.ViewModels") #>;
13 | using <#= AppendNamespaceHierarchyTo(SolutionName + ".Core.QueryDtos") #>;
14 | <#+ if (EntityScaffoldingDetails.NamespaceHierarchy != null) {
15 | #>using <#= SolutionName + ".Core" #>;<#+ } #>
16 |
17 | namespace <#= AppendNamespaceHierarchyTo(SolutionName + ".ApplicationServices") #>
18 | {
19 | public interface I<#= EntityScaffoldingDetails.EntityName #>ManagementService
20 | {
21 | <#= EntityScaffoldingDetails.EntityName #>FormViewModel CreateFormViewModel();
22 | <#= EntityScaffoldingDetails.EntityName #>FormViewModel CreateFormViewModelFor(int <#= EntityScaffoldingDetails.EntityNameCamelCase #>Id);
23 | <#= EntityScaffoldingDetails.EntityName #>FormViewModel CreateFormViewModelFor(<#= EntityScaffoldingDetails.EntityName #> <#= EntityScaffoldingDetails.EntityNameCamelCase #>);
24 | <#= EntityScaffoldingDetails.EntityName #> Get(int id);
25 | IList<<#= EntityScaffoldingDetails.EntityName #>> GetAll();
26 | IList<<#= EntityScaffoldingDetails.EntityName #>Dto> Get<#= EntityScaffoldingDetails.EntityName #>Summaries();
27 | ActionConfirmation SaveOrUpdate(<#= EntityScaffoldingDetails.EntityName #> <#= EntityScaffoldingDetails.EntityNameCamelCase #>);
28 | ActionConfirmation UpdateWith(<#= EntityScaffoldingDetails.EntityName #> <#= EntityScaffoldingDetails.EntityNameCamelCase #>FromForm, int idOf<#= EntityScaffoldingDetails.EntityName #>ToUpdate);
29 | ActionConfirmation Delete(int id);
30 | }
31 | }
32 | <#+ return this.GenerationEnvironment.ToString();
33 | }
34 | }
35 | #>
36 |
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/Templates/ApplicationServices/ViewModels/DomainObjectFormViewModel.tt:
--------------------------------------------------------------------------------
1 | <#+
2 | public class DomainObjectFormViewModel : BaseTemplate
3 | {
4 | public DomainObjectFormViewModel(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
5 | : base(solutionName, entityScaffoldingDetails) { }
6 |
7 | public override string TransformText()
8 | {
9 | #>
10 | using <#= AppendNamespaceHierarchyTo(SolutionName + ".Core") #>;
11 |
12 | namespace <#= AppendNamespaceHierarchyTo(SolutionName + ".ApplicationServices.ViewModels") #>
13 | {
14 | public class <#= EntityScaffoldingDetails.EntityName #>FormViewModel
15 | {
16 | public <#= EntityScaffoldingDetails.EntityName #> <#= EntityScaffoldingDetails.EntityName #> { get; set; }
17 | }
18 | }
19 | <#+ return this.GenerationEnvironment.ToString();
20 | }
21 | }
22 | #>
23 |
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/Templates/BaseTemplate.tt:
--------------------------------------------------------------------------------
1 | <#@ assembly name="$(SolutionDir)lib\Inflector.Net.dll" #>
2 |
3 | <#+
4 | public abstract class BaseTemplate : Template
5 | {
6 | public BaseTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails) {
7 | this.solutionName = solutionName;
8 | this.entityScaffoldingDetails = entityScaffoldingDetails;
9 | }
10 |
11 | protected string SolutionName {
12 | get { return solutionName; }
13 | }
14 |
15 | protected EntityScaffoldingDetails EntityScaffoldingDetails {
16 | get { return entityScaffoldingDetails; }
17 | }
18 |
19 | protected string AppendNamespaceHierarchyTo(string namespacePath) {
20 | if (entityScaffoldingDetails.NamespaceHierarchy == null ||
21 | entityScaffoldingDetails.NamespaceHierarchy.Length == 0)
22 | return namespacePath;
23 |
24 | foreach (string namespaceToAppend in entityScaffoldingDetails.NamespaceHierarchy) {
25 | namespacePath += "." + namespaceToAppend;
26 | }
27 |
28 | return namespacePath;
29 | }
30 |
31 | protected string EntityBaseUrl {
32 | get {
33 | return ((entityScaffoldingDetails.NamespaceHierarchy != null && entityScaffoldingDetails.NamespaceHierarchy.Length > 0)
34 | ? (AppendNamespaceHierarchyTo("").Substring(1).Replace(".", "/") + "/")
35 | : "") +
36 | entityScaffoldingDetails.EntityNamePlural + "/";
37 | }
38 | }
39 |
40 | private readonly string solutionName;
41 | private readonly EntityScaffoldingDetails entityScaffoldingDetails;
42 | }
43 | #>
44 |
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/Templates/Core/ActionConfirmationTemplate.tt:
--------------------------------------------------------------------------------
1 | <#+
2 | public class ActionConfirmationTemplate : BaseTemplate
3 | {
4 | public ActionConfirmationTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
5 | : base(solutionName, entityScaffoldingDetails) { }
6 |
7 | public override string TransformText()
8 | {
9 | #>
10 | namespace <#= SolutionName #>.Core
11 | {
12 | public class ActionConfirmation
13 | {
14 | private ActionConfirmation() { }
15 |
16 | public static ActionConfirmation CreateSuccessConfirmation(string message) {
17 | ActionConfirmation confirmation = new ActionConfirmation();
18 | confirmation.Message = message;
19 | confirmation.WasSuccessful = true;
20 | return confirmation;
21 | }
22 |
23 | public static ActionConfirmation CreateFailureConfirmation(string message) {
24 | ActionConfirmation confirmation = new ActionConfirmation();
25 | confirmation.Message = message;
26 | confirmation.WasSuccessful = false;
27 | return confirmation;
28 | }
29 |
30 | public bool WasSuccessful { get; private set; }
31 | public string Message { get; set; }
32 | public object Value { get; set; }
33 | }
34 | }
35 | <#+ return this.GenerationEnvironment.ToString();
36 | }
37 | }
38 | #>
39 |
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/Templates/Core/DomainObjectTemplate.tt:
--------------------------------------------------------------------------------
1 | <#@ import namespace="System.Collections" #>
2 |
3 | <#+
4 | public class DomainObjectTemplate : BaseTemplate
5 | {
6 | public DomainObjectTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
7 | : base(solutionName, entityScaffoldingDetails) { }
8 |
9 | public override string TransformText()
10 | {
11 | #>
12 | using System;
13 | using NHibernate.Validator.Constraints;
14 | using SharpArch.Core.DomainModel;
15 |
16 | namespace <#= AppendNamespaceHierarchyTo(SolutionName + ".Core") #>
17 | {
18 | public class <#= EntityScaffoldingDetails.EntityName #> : Entity
19 | {<#+
20 | PushIndent("\t\t");
21 |
22 | foreach (EntityProperty property in EntityScaffoldingDetails.EntityProperties) {
23 | WriteLine("");
24 |
25 | if (property.IsPartOfDomainSignature)
26 | WriteLine("[DomainSignature]");
27 |
28 | if (! string.IsNullOrEmpty(property.PropertyAttributes))
29 | WriteLine(property.PropertyAttributes);
30 |
31 | WriteLine("public virtual " + property.TypeName + " " + property.PropertyName + " { get; set; }");
32 | }
33 |
34 | PopIndent();
35 | #>
36 | }
37 | }
38 | <#+ return this.GenerationEnvironment.ToString();
39 | }
40 | }
41 | #>
42 |
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/Templates/Core/QueryDtos/DomainObjectDtoTemplate.tt:
--------------------------------------------------------------------------------
1 | <#@ import namespace="System.Collections" #>
2 |
3 | <#+
4 | public class DomainObjectDtoTemplate : BaseTemplate
5 | {
6 | public DomainObjectDtoTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
7 | : base(solutionName, entityScaffoldingDetails) { }
8 |
9 | public override string TransformText()
10 | {
11 | #>
12 | using System;
13 |
14 | namespace <#= AppendNamespaceHierarchyTo(SolutionName + ".Core.QueryDtos") #>
15 | {
16 | public class <#= EntityScaffoldingDetails.EntityName #>Dto
17 | {
18 | public int Id { get; set; }
19 | <#+
20 | PushIndent("\t\t");
21 |
22 | foreach (EntityProperty property in EntityScaffoldingDetails.EntityProperties) {
23 | WriteLine("public " + property.TypeName + " " + property.PropertyName + " { get; set; }");
24 | }
25 |
26 | PopIndent();
27 | #>
28 | }
29 | }
30 | <#+ return this.GenerationEnvironment.ToString();
31 | }
32 | }
33 | #>
34 |
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/Templates/Core/RepositoryInterfaces/IDomainObjectRepositoryTemplate.tt:
--------------------------------------------------------------------------------
1 | <#+
2 | public class IDomainObjectRepositoryTemplate : BaseTemplate
3 | {
4 | public IDomainObjectRepositoryTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
5 | : base(solutionName, entityScaffoldingDetails) { }
6 |
7 | public override string TransformText()
8 | {
9 | #>
10 | using SharpArch.Core.PersistenceSupport;
11 | using System.Collections.Generic;
12 | using <#= AppendNamespaceHierarchyTo(SolutionName + ".Core") #>;
13 | using <#= AppendNamespaceHierarchyTo(SolutionName + ".Core.QueryDtos") #>;
14 |
15 | namespace <#= AppendNamespaceHierarchyTo(SolutionName + ".Core.RepositoryInterfaces") #>
16 | {
17 | public interface I<#= EntityScaffoldingDetails.EntityName #>Repository : IRepository<<#= EntityScaffoldingDetails.EntityName #>>
18 | {
19 | IList<<#= EntityScaffoldingDetails.EntityName #>Dto> Get<#= EntityScaffoldingDetails.EntityName #>Summaries();
20 | }
21 | }
22 | <#+ return this.GenerationEnvironment.ToString();
23 | }
24 | }
25 | #>
26 |
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/Templates/Data/NamedQueries/GetDomainObjectSummariesHbmTemplate.tt:
--------------------------------------------------------------------------------
1 | <#+
2 | public class GetDomainObjectSummariesHbmTemplate : BaseTemplate
3 | {
4 | public GetDomainObjectSummariesHbmTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
5 | : base(solutionName, entityScaffoldingDetails) { }
6 |
7 | public override string TransformText()
8 | {
9 | #>
10 |
11 |
12 |
13 | SET NOCOUNT ON;
14 |
15 | SELECT Id<#+
16 | foreach (EntityProperty property in EntityScaffoldingDetails.EntityProperties) {
17 | Write(", " + property.PropertyName);
18 | }
19 |
20 | WriteLine("");
21 | #>
22 | FROM <#= EntityScaffoldingDetails.EntityNamePlural #>
23 |
24 |
25 | <#+ return this.GenerationEnvironment.ToString();
26 | }
27 | }
28 | #>
29 |
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/Templates/Data/Repositories/DomainObjectRepositoryTemplate.tt:
--------------------------------------------------------------------------------
1 | <#@ import namespace="System.Collections" #>
2 |
3 | <#+
4 | public class DomainObjectRepositoryTemplate : BaseTemplate
5 | {
6 | public DomainObjectRepositoryTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
7 | : base(solutionName, entityScaffoldingDetails) { }
8 |
9 | public override string TransformText()
10 | {
11 | #>
12 | using SharpArch.Data.NHibernate;
13 | using System.Collections.Generic;
14 | using NHibernate;
15 | using NHibernate.Transform;
16 | using <#= AppendNamespaceHierarchyTo(SolutionName + ".Core") #>;
17 | using <#= AppendNamespaceHierarchyTo(SolutionName + ".Core.QueryDtos") #>;
18 | using <#= AppendNamespaceHierarchyTo(SolutionName + ".Core.RepositoryInterfaces") #>;
19 |
20 | namespace <#= AppendNamespaceHierarchyTo(SolutionName + ".Data.Repositories") #>
21 | {
22 | public class <#= EntityScaffoldingDetails.EntityName #>Repository : Repository<<#= EntityScaffoldingDetails.EntityName #>>, I<#= EntityScaffoldingDetails.EntityName #>Repository
23 | {
24 | public IList<<#= EntityScaffoldingDetails.EntityName #>Dto> Get<#= EntityScaffoldingDetails.EntityName #>Summaries() {
25 | ISession session = SharpArch.Data.NHibernate.NHibernateSession.Current;
26 |
27 | IQuery query = session.GetNamedQuery("Get<#= EntityScaffoldingDetails.EntityName #>Summaries")
28 | .SetResultTransformer(Transformers.AliasToBean<<#= EntityScaffoldingDetails.EntityName #>Dto>());
29 |
30 | return query.List<<#= EntityScaffoldingDetails.EntityName #>Dto>();
31 | }
32 | }
33 | }
34 | <#+ return this.GenerationEnvironment.ToString();
35 | }
36 | }
37 | #>
38 |
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/Templates/Tests/Core/DomainObjectInstanceFactoryTemplate.tt:
--------------------------------------------------------------------------------
1 | <#+
2 | public class DomainObjectInstanceFactoryTemplate : BaseTemplate
3 | {
4 | public DomainObjectInstanceFactoryTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
5 | : base(solutionName, entityScaffoldingDetails) { }
6 |
7 | public override string TransformText()
8 | {
9 | #>
10 | using System;
11 | using <#= AppendNamespaceHierarchyTo(SolutionName + ".Core") #>;
12 |
13 | namespace <#= AppendNamespaceHierarchyTo("Tests." + SolutionName + ".Core") #>
14 | {
15 | public class <#= EntityScaffoldingDetails.EntityName #>InstanceFactory
16 | {
17 | public static <#= EntityScaffoldingDetails.EntityName #> CreateValidTransient<#= EntityScaffoldingDetails.EntityName #>() {
18 | return new <#= EntityScaffoldingDetails.EntityName #>() {
19 | <#+
20 | PushIndent("\t\t\t\t");
21 |
22 | for (int i=0; i < EntityScaffoldingDetails.EntityProperties.Count; i++) {
23 | if (i > 0) {
24 | WriteLine(", ");
25 | }
26 |
27 | Write(EntityScaffoldingDetails.EntityProperties[i].PropertyName + " = " + EntityScaffoldingDetails.EntityProperties[i].GetDefaultValueForTests());
28 | }
29 |
30 | PopIndent();
31 | #>
32 | };
33 | }
34 | }
35 | }
36 | <#+ return this.GenerationEnvironment.ToString();
37 | }
38 | }
39 | #>
40 |
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/Templates/Tests/Core/DomainObjectTestsTemplate.tt:
--------------------------------------------------------------------------------
1 | <#+
2 | public class DomainObjectTestsTemplate : BaseTemplate
3 | {
4 | public DomainObjectTestsTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
5 | : base(solutionName, entityScaffoldingDetails) { }
6 |
7 | public override string TransformText()
8 | {
9 | #>
10 | using NUnit.Framework;
11 | using SharpArch.Testing;
12 | using SharpArch.Testing.NUnit;
13 | using <#= AppendNamespaceHierarchyTo(SolutionName + ".Core") #>;
14 |
15 | namespace <#= AppendNamespaceHierarchyTo("Tests." + SolutionName + ".Core") #>
16 | {
17 | <#+
18 | if (! EntityScaffoldingDetails.HasAnyDomainSignatureProperties) { #>
19 | ///
20 | /// A <#= EntityScaffoldingDetails.EntityNameCamelCase #>'s ID property is the only property which is compared to
21 | /// another <#= EntityScaffoldingDetails.EntityNameCamelCase #>. I.e., it does not have any domain signature
22 | /// properties other than the Id itself.
23 | ///
24 | <#+
25 | }
26 | #>
27 | [TestFixture]
28 | public class <#= EntityScaffoldingDetails.EntityName #>Tests
29 | {
30 | [Test]
31 | public void CanCompare<#= EntityScaffoldingDetails.EntityNamePlural #>() {
32 | <#= EntityScaffoldingDetails.EntityName #> instance = new <#= EntityScaffoldingDetails.EntityName #>();
33 | <#+
34 | PushIndent("\t\t\t");
35 |
36 | if (EntityScaffoldingDetails.HasAnyDomainSignatureProperties) {
37 | foreach (EntityProperty property in EntityScaffoldingDetails.EntityProperties) {
38 | if (property.IsPartOfDomainSignature) {
39 | WriteLine("instance." + property.PropertyName + " = " + property.GetDefaultValueForTests() + ";");
40 | }
41 | }
42 | }
43 | else {
44 | WriteLine("EntityIdSetter.SetIdOf(instance, 1);");
45 | }
46 |
47 | PopIndent();
48 | #>
49 |
50 | <#= EntityScaffoldingDetails.EntityName #> instanceToCompareTo = new <#= EntityScaffoldingDetails.EntityName #>();
51 | <#+
52 | PushIndent("\t\t\t");
53 |
54 | if (EntityScaffoldingDetails.HasAnyDomainSignatureProperties) {
55 | foreach (EntityProperty property in EntityScaffoldingDetails.EntityProperties) {
56 | if (property.IsPartOfDomainSignature) {
57 | WriteLine("instanceToCompareTo." + property.PropertyName + " = " + property.GetDefaultValueForTests() + ";");
58 | }
59 | }
60 | }
61 | else {
62 | WriteLine("EntityIdSetter.SetIdOf(instanceToCompareTo, 1);");
63 | }
64 |
65 | PopIndent();
66 | #>
67 |
68 | instance.ShouldEqual(instanceToCompareTo);
69 | }
70 | }
71 | }
72 | <#+ return this.GenerationEnvironment.ToString();
73 | }
74 | }
75 | #>
76 |
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/Templates/Web/Controllers/AreaRegistrationTemplate.tt:
--------------------------------------------------------------------------------
1 | <#@ import namespace="System.Collections" #>
2 |
3 | <#+
4 | public class AreaRegistrationTemplate : BaseTemplate
5 | {
6 |
7 | public AreaRegistrationTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
8 | : base(solutionName, entityScaffoldingDetails) { }
9 |
10 | public override string TransformText()
11 | {
12 |
13 | #>
14 |
15 | namespace <#= AppendNamespaceHierarchyTo(SolutionName + ".Web.Controllers") #>
16 | {
17 |
18 | public class <#= AppendNamespaceHierarchyTo("").Replace(".", "/").Trim('/') #>AreaRegistration : System.Web.Mvc.AreaRegistration
19 | {
20 | public override string AreaName {
21 | get {
22 | return "<#= AppendNamespaceHierarchyTo("").Replace(".", "/").Trim('/') #>";
23 | }
24 | }
25 |
26 | public override void RegisterArea(System.Web.Mvc.AreaRegistrationContext context) {
27 | context.MapRoute(
28 | "<#= AppendNamespaceHierarchyTo("").Replace(".", "") #>_default",
29 | "<#= AppendNamespaceHierarchyTo("").Replace(".", "/").Trim('/') #>/{controller}/{action}/{id}",
30 | new { action = "Index", id = "" }
31 | );
32 | }
33 | }
34 |
35 | } <#+
36 | return this.GenerationEnvironment.ToString();
37 | }
38 |
39 | }
40 | #>
41 |
42 |
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/Templates/Web/Views/CreateTemplate.tt:
--------------------------------------------------------------------------------
1 | <#+
2 | public class CreateTemplate : BaseTemplate
3 | {
4 | public CreateTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
5 | : base(solutionName, entityScaffoldingDetails) { }
6 |
7 | public override string TransformText()
8 | {
9 | #>
10 | <%@ Page Title="Create <#= EntityScaffoldingDetails.EntityName #>" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true"
11 | Inherits="System.Web.Mvc.ViewPage<<#= AppendNamespaceHierarchyTo(SolutionName + ".ApplicationServices.ViewModels") + "." + EntityScaffoldingDetails.EntityName + "FormViewModel" #>>" %>
12 |
13 |
14 |
15 | Create <#= EntityScaffoldingDetails.EntityName #>
16 |
17 | <% Html.RenderPartial("<#= EntityScaffoldingDetails.EntityName #>Form", ViewData); %>
18 |
19 |
20 | <#+return this.GenerationEnvironment.ToString();
21 | }
22 | }
23 | #>
24 |
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/Templates/Web/Views/DomainObjectFormTemplate.tt:
--------------------------------------------------------------------------------
1 | <#@ import namespace="System.Collections" #>
2 |
3 | <#+
4 | public class DomainObjectFormTemplate : BaseTemplate
5 | {
6 | public DomainObjectFormTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
7 | : base(solutionName, entityScaffoldingDetails) { }
8 |
9 | public override string TransformText()
10 | {
11 | #>
12 | <%@ Control Language="C#" AutoEventWireup="true"
13 | Inherits="System.Web.Mvc.ViewUserControl<<#= AppendNamespaceHierarchyTo(SolutionName + ".ApplicationServices.ViewModels") + "." + EntityScaffoldingDetails.EntityName + "FormViewModel" #>>" %>
14 | <%@ Import Namespace="<#= AppendNamespaceHierarchyTo(SolutionName + ".Core") #>" %>
15 | <%@ Import Namespace="<#= SolutionName #>.Web.Controllers" %>
16 | <#+ if (EntityScaffoldingDetails.NamespaceHierarchy != null) {
17 | #><%@ Import Namespace="<#= AppendNamespaceHierarchyTo(SolutionName + ".Web.Controllers") #>" %><#+ } #>
18 |
19 | <% if (ViewContext.TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] != null) { %>
20 | <%= ViewContext.TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()]%>
21 | <% } %>
22 |
23 | <%= Html.ValidationSummary() %>
24 |
25 | <% using (Html.BeginForm()) { %>
26 | <%= Html.AntiForgeryToken() %>
27 | <%= Html.Hidden("<#= EntityScaffoldingDetails.EntityName #>.Id", (ViewData.Model.<#= EntityScaffoldingDetails.EntityName #> != null) ? ViewData.Model.<#= EntityScaffoldingDetails.EntityName #>.Id : 0)%>
28 |
29 |
50 | <% } %>
51 | <#+ return this.GenerationEnvironment.ToString();
52 | }
53 | }
54 | #>
55 |
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/Templates/Web/Views/EditTemplate.tt:
--------------------------------------------------------------------------------
1 | <#+
2 | public class EditTemplate : BaseTemplate
3 | {
4 | public EditTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
5 | : base(solutionName, entityScaffoldingDetails) { }
6 |
7 | public override string TransformText()
8 | {
9 | #>
10 | <%@ Page Title="Edit <#= EntityScaffoldingDetails.EntityName #>" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true"
11 | Inherits="System.Web.Mvc.ViewPage<<#= AppendNamespaceHierarchyTo(SolutionName + ".ApplicationServices.ViewModels") + "." + EntityScaffoldingDetails.EntityName + "FormViewModel" #>>" %>
12 |
13 |
14 |
15 | Edit <#= EntityScaffoldingDetails.EntityName #>
16 |
17 | <% Html.RenderPartial("<#= EntityScaffoldingDetails.EntityName #>Form", ViewData); %>
18 |
19 |
20 | <#+ return this.GenerationEnvironment.ToString();
21 | }
22 | }
23 | #>
24 |
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/Templates/Web/Views/IndexTemplate.tt:
--------------------------------------------------------------------------------
1 | <#@ import namespace="System.Collections" #>
2 |
3 | <#+
4 | public class IndexTemplate : BaseTemplate
5 | {
6 | public IndexTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
7 | : base(solutionName, entityScaffoldingDetails) { }
8 |
9 | public override string TransformText()
10 | {
11 | #>
12 | <%@ Page Title="<#= EntityScaffoldingDetails.EntityNamePlural #>" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true"
13 | Inherits="System.Web.Mvc.ViewPage>>" %>
14 | <%@ Import Namespace="<#= AppendNamespaceHierarchyTo(SolutionName + ".Core.QueryDtos") #>" %>
15 | <%@ Import Namespace="<#= SolutionName #>.Web.Controllers" %>
16 | <#+ if (EntityScaffoldingDetails.NamespaceHierarchy != null) {
17 | #><%@ Import Namespace="<#= AppendNamespaceHierarchyTo(SolutionName + ".Web.Controllers") #>" %><#+ } #>
18 |
19 |
20 |
21 | <#= EntityScaffoldingDetails.EntityNamePlural #>
22 |
23 | <% if (ViewContext.TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] != null) { %>
24 | <%= ViewContext.TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()]%>
25 | <% } %>
26 |
27 |
62 |
63 | <%= Html.ActionLink<<#= EntityScaffoldingDetails.EntityNamePlural #>Controller>(c => c.Create(), "Create New <#= EntityScaffoldingDetails.EntityName #>") %>
64 |
65 |
66 | <#+ return this.GenerationEnvironment.ToString();
67 | }
68 | }
69 | #>
70 |
--------------------------------------------------------------------------------
/tools/CrudScaffoldingForEnterpriseApp/Templates/Web/Views/ShowTemplate.tt:
--------------------------------------------------------------------------------
1 | <#@ import namespace="System.Collections" #>
2 |
3 | <#+
4 | public class ShowTemplate : BaseTemplate
5 | {
6 | public ShowTemplate(string solutionName, EntityScaffoldingDetails entityScaffoldingDetails)
7 | : base(solutionName, entityScaffoldingDetails) { }
8 |
9 | public override string TransformText()
10 | {
11 | #>
12 | <%@ Page Title="<#= EntityScaffoldingDetails.EntityName #> Details" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true"
13 | Inherits="System.Web.Mvc.ViewPage<<#= AppendNamespaceHierarchyTo(SolutionName + ".Core") #>.<#= EntityScaffoldingDetails.EntityName #>>" %>
14 | <%@ Import Namespace="<#= AppendNamespaceHierarchyTo(SolutionName + ".Web.Controllers") #>" %>
15 |
16 |
17 |
18 | <#= EntityScaffoldingDetails.EntityName #> Details
19 |
20 |
21 | <#+
22 | foreach (EntityProperty property in EntityScaffoldingDetails.EntityProperties) {
23 | #>
24 |
25 | <#= property.PropertyName #>:
26 | <%= Server.HtmlEncode(ViewData.Model.<#= property.PropertyName #>.ToString()) %>
27 |
28 | <#+
29 | }
30 | #>
31 |
32 | <%= Html.Button("btnBack", "Back", HtmlButtonType.Button,
33 | "window.location.href = '" + Html.BuildUrlFromExpressionForAreas<<#= EntityScaffoldingDetails.EntityNamePlural #>Controller>(c => c.Index()) + "';") %>
34 |
35 |
36 |
37 |
38 | <#+ return this.GenerationEnvironment.ToString();
39 | }
40 | }
41 | #>
42 |
--------------------------------------------------------------------------------
/tools/lib/MvcContrib.TestHelper.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/tools/lib/MvcContrib.TestHelper.dll
--------------------------------------------------------------------------------
/tools/lib/Rhino.Mocks.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/tools/lib/Rhino.Mocks.dll
--------------------------------------------------------------------------------
/tools/lib/SharpArch.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/tools/lib/SharpArch.dll
--------------------------------------------------------------------------------
/tools/lib/System.Data.SQLite.DLL:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/tools/lib/System.Data.SQLite.DLL
--------------------------------------------------------------------------------
/tools/lib/nunit.framework.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowfeather/SharpArchitecture-MultiTenant/375a0f9c0812b335794d0ca2564a9b628542861b/tools/lib/nunit.framework.dll
--------------------------------------------------------------------------------