├── .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 | CWS3x��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����N TyE����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 |
    18 |
  • 19 | 20 | 21 | 24 |
  • 25 |
  • 26 | <%= Html.SubmitButton("submit", "Import") %> or <%= Html.ActionLink(c => c.Index(null), "Cancel")%> 27 |
  • 28 |
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 |
  1. 14 | Create your database and set the connection string 15 | within SharpArchitecture.MultiTenant.Web/NHibernate.config 16 |
  2. 17 |
  3. 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 |
  4. 22 |
  5. 23 | Open SharpArchitecture.MultiTenant.Tests.dll via NUnit and make sure all the tests are turning green. 24 |
  6. 25 |
  7. 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 |
  8. 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 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | <% foreach (string key in ViewData.ModelState.Keys) { %> 18 | 19 | 20 | 21 | 22 | 23 | 36 | 37 | <% } %> 38 | 39 |
KeyAttempted Value (for display purposes)Raw ValueError CountError 1 Message
<%= key %><%= ViewData.ModelState[key].Value.AttemptedValue %><%= ViewData.ModelState[key].Value.RawValue %><%= ViewData.ModelState[key].Errors.Count %> 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 |
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 |
47 | 48 |
49 | 50 |
51 |
52 | 53 |
54 | 55 | 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 |
    32 | <#+ 33 | foreach (EntityProperty property in EntityScaffoldingDetails.EntityProperties) { 34 | #> 35 |
  • 36 | <%= Html.LabelFor(m => m.<#= EntityScaffoldingDetails.EntityName #>.<#= property.PropertyName #>) %> 37 |
    <%= Html.TextBoxFor(m => m.<#= EntityScaffoldingDetails.EntityName #>.<#= property.PropertyName #>) %>
    38 | <%= Html.ValidationMessageFor(m => m.<#= EntityScaffoldingDetails.EntityName #>.<#= property.PropertyName #>) %> 39 |
  • 40 | <#+ 41 | } 42 | #> 43 |
  • 44 | <%= Html.SubmitButton("btnSave", "Save <#= EntityScaffoldingDetails.EntityName #>") %> 45 | <%= Html.Button("btnCancel", "Cancel", HtmlButtonType.Button, 46 | "window.location.href = '" + Html.BuildUrlFromExpressionForAreas<<#= EntityScaffoldingDetails.EntityNamePlural #>Controller>(c => c.Index()) + "';") %> 47 |
  • 48 |
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 | 28 | 29 | 30 | <#+ 31 | foreach (EntityProperty property in EntityScaffoldingDetails.EntityProperties) { 32 | #> 33 | 34 | <#+ 35 | } 36 | #> 37 | 38 | 39 | 40 | 41 | <% 42 | foreach (<#= EntityScaffoldingDetails.EntityName #> <#= EntityScaffoldingDetails.EntityNameCamelCase #> in ViewData.Model) { %> 43 | 44 | <#+ 45 | foreach (EntityProperty property in EntityScaffoldingDetails.EntityProperties) { 46 | #> 47 | 48 | <#+ 49 | } 50 | #> 51 | 52 | 53 | 59 | 60 | <%} %> 61 |
<#= property.PropertyName #>Action
<%= <#= EntityScaffoldingDetails.EntityNameCamelCase #>.<#= property.PropertyName #> %><%=Html.ActionLink<<#= EntityScaffoldingDetails.EntityNamePlural #>Controller>( c => c.Show( <#= EntityScaffoldingDetails.EntityNameCamelCase #>.Id ), "Details ") %><%=Html.ActionLink<<#= EntityScaffoldingDetails.EntityNamePlural #>Controller>( c => c.Edit( <#= EntityScaffoldingDetails.EntityNameCamelCase #>.Id ), "Edit") %> 54 | <% using (Html.BeginForm<<#= EntityScaffoldingDetails.EntityNamePlural #>Controller>(c => c.Delete(<#= EntityScaffoldingDetails.EntityNameCamelCase #>.Id))) { %> 55 | <%= Html.AntiForgeryToken() %> 56 | 57 | <% } %> 58 |
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 | 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 |
    30 | <#+ 31 | foreach (EntityProperty property in EntityScaffoldingDetails.EntityProperties) { 32 | #> 33 |
  • 34 | 35 |
    36 | <%= Html.TextBox("<#= EntityScaffoldingDetails.EntityName #>.<#= property.PropertyName #>", 37 | (ViewData.Model.<#= EntityScaffoldingDetails.EntityName #> != null) ? ViewData.Model.<#= EntityScaffoldingDetails.EntityName #>.<#= property.PropertyName #>.ToString() : "")%> 38 |
    39 | <%= Html.ValidationMessage("<#= EntityScaffoldingDetails.EntityName #>.<#= property.PropertyName #>")%> 40 |
  • 41 | <#+ 42 | } 43 | #> 44 |
  • 45 | <%= Html.SubmitButton("btnSave", "Save <#= EntityScaffoldingDetails.EntityName #>") %> 46 | <%= Html.Button("btnCancel", "Cancel", HtmlButtonType.Button, 47 | "window.location.href = '" + Html.BuildUrlFromExpressionForAreas<<#= EntityScaffoldingDetails.EntityNamePlural #>Controller>(c => c.Index()) + "';") %> 48 |
  • 49 |
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 | 28 | 29 | 30 | <#+ 31 | foreach (EntityProperty property in EntityScaffoldingDetails.EntityProperties) { 32 | #> 33 | 34 | <#+ 35 | } 36 | #> 37 | 38 | 39 | 40 | 41 | <% 42 | foreach (<#= EntityScaffoldingDetails.EntityName #>Dto <#= EntityScaffoldingDetails.EntityNameCamelCase #>Dto in ViewData.Model) { %> 43 | 44 | <#+ 45 | foreach (EntityProperty property in EntityScaffoldingDetails.EntityProperties) { 46 | #> 47 | 48 | <#+ 49 | } 50 | #> 51 | 52 | 53 | 59 | 60 | <%} %> 61 |
<#= property.PropertyName #>Action
<%= <#= EntityScaffoldingDetails.EntityNameCamelCase #>Dto.<#= property.PropertyName #> %><%=Html.ActionLink<<#= EntityScaffoldingDetails.EntityNamePlural #>Controller>( c => c.Show( <#= EntityScaffoldingDetails.EntityNameCamelCase #>Dto.Id ), "Details ") %><%=Html.ActionLink<<#= EntityScaffoldingDetails.EntityNamePlural #>Controller>( c => c.Edit( <#= EntityScaffoldingDetails.EntityNameCamelCase #>Dto.Id ), "Edit") %> 54 | <% using (Html.BeginForm<<#= EntityScaffoldingDetails.EntityNamePlural #>Controller>(c => c.Delete(<#= EntityScaffoldingDetails.EntityNameCamelCase #>Dto.Id))) { %> 55 | <%= Html.AntiForgeryToken() %> 56 | 57 | <% } %> 58 |
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 | 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 --------------------------------------------------------------------------------