├── .github └── workflows │ └── build.yml ├── .gitignore ├── LICENSE.txt ├── README.md ├── TinyIoC.sln ├── build ├── TinyIoC.png ├── TinyIoC.psd └── common.props ├── samples └── ASPNet │ ├── MvcTestApplication.sln │ └── MvcTestApplication │ ├── ApplicationDependencyClass.cs │ ├── Content │ └── Site.css │ ├── Controllers │ ├── AccountController.cs │ └── HomeController.cs │ ├── Global.asax │ ├── Global.asax.cs │ ├── IApplicationDependency.cs │ ├── IRequestDependency.cs │ ├── Models │ └── AccountModels.cs │ ├── MvcTestApplication.csproj │ ├── Properties │ └── AssemblyInfo.cs │ ├── RequestDependencyClass.cs │ ├── Views │ ├── Account │ │ ├── ChangePassword.aspx │ │ ├── ChangePasswordSuccess.aspx │ │ ├── LogOn.aspx │ │ └── Register.aspx │ ├── Home │ │ ├── About.aspx │ │ └── Index.aspx │ ├── Shared │ │ ├── Error.aspx │ │ ├── LogOnUserControl.ascx │ │ └── Site.Master │ └── Web.config │ ├── Web.Debug.config │ ├── Web.Release.config │ ├── Web.config │ └── packages.config ├── src ├── Directory.Build.props ├── TinyIoC.AspNetExtensions │ ├── TinyIoC.AspNetExtensions.csproj │ └── TinyIoCAspNetExtensions.cs ├── TinyIoC │ ├── TinyIoC.cs │ └── TinyIoC.csproj └── TinyMessenger │ ├── TinyMessenger.cs │ └── TinyMessenger.csproj └── tests ├── Directory.Build.props ├── TinyIoC.Tests.ExternalTypes ├── ExternalTestClasses.cs └── TinyIoC.Tests.ExternalTypes.csproj ├── TinyIoC.Tests ├── Fakes │ └── FakeLifetimeProvider.cs ├── Helpers │ ├── AssertHelper.cs │ └── ExceptionHelper.cs ├── PlatformTestSuite │ └── PlatformTests.cs ├── TestData │ ├── BasicClasses.cs │ ├── NestedClassDependencies.cs │ ├── NestedInterfaceDependencies.cs │ ├── TinyMessengerTestData.cs │ └── UtilityMethods.cs ├── TinyIoC.Tests.csproj ├── TinyIoCFunctionalTests.cs ├── TinyIoCTests.cs ├── TinyMessageSubscriptionTokenTests.cs ├── TinyMessengerTests.cs └── TypeExtensionsTests.cs └── TinyIoc.Benchmarks ├── AutoRegisterBenchmarks.cs ├── Program.cs ├── ResolveBenchmarks.cs ├── TinyIoc.Benchmarks.csproj └── TinyIocOriginal.cs /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: [push, pull_request] 3 | env: 4 | DOTNET_CLI_TELEMETRY_OPTOUT: 1 5 | jobs: 6 | build: 7 | runs-on: windows-latest 8 | steps: 9 | - name: Checkout 10 | uses: actions/checkout@v1 11 | with: 12 | fetch-depth: 0 13 | - name: Setup .NET Core 14 | uses: actions/setup-dotnet@v1 15 | with: 16 | dotnet-version: 3.1.201 17 | - name: Build Reason 18 | run: "echo ref: ${{github.ref}} event: ${{github.event_name}}" 19 | - name: Build Version 20 | id: version 21 | uses: thefringeninja/action-minver@2.0.0-preview1 22 | - name: Build 23 | run: dotnet build --configuration Release TinyIoC.sln 24 | - name: Run Tests 25 | run: dotnet test --configuration Release --results-directory artifacts --no-build --logger:trx TinyIoC.sln 26 | - name: Package 27 | if: github.event_name != 'pull_request' 28 | run: dotnet pack --configuration Source 29 | - name: Publish CI Packages 30 | shell: bash 31 | run: | 32 | for package in $(find -name "*.nupkg" | grep "minver" -v); do 33 | echo "${0##*/}": Pushing $package... 34 | 35 | # GPR 36 | # workaround for GPR push issue 37 | curl -sX PUT -u "TinyIoC:${{ secrets.GITHUB_TOKEN }}" -F package=@$package https://nuget.pkg.github.com/TinyIoC/ 38 | done 39 | - name: Publish Release Packages 40 | shell: bash 41 | if: startsWith(github.ref, 'refs/tags/') 42 | run: | 43 | for package in $(find -name "*.nupkg" | grep "minver" -v); do 44 | echo "${0##*/}": Pushing $package... 45 | dotnet nuget push $package --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_KEY }} 46 | done 47 | - name: Upload Artifacts 48 | uses: actions/upload-artifact@v1.0.0 49 | with: 50 | name: artifacts 51 | path: artifacts 52 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore file for Visual Studio 2008 2 | 3 | # use glob syntax 4 | syntax: glob 5 | 6 | # Ignore Visual Studio 2008 files 7 | *.tss 8 | *.csproj.orig 9 | *.obj 10 | *.pdb 11 | *.user 12 | *.aps 13 | *.pch 14 | *.vspscc 15 | *_i.c 16 | *_p.c 17 | *.ncb 18 | *.suo 19 | *.tlb 20 | *.tlh 21 | *.bak 22 | *.cache 23 | *.ilk 24 | *.log 25 | *.lib 26 | *.sbr 27 | *.scc 28 | *.cs.orig 29 | [Bb]in 30 | [Db]ebug*/ 31 | obj/ 32 | [Rr]elease*/ 33 | _ReSharper*/ 34 | [Tt]est[Rr]esult* 35 | [Bb]uild[Ll]og.* 36 | *.[Pp]ublish.xml 37 | *.ncrunchproject 38 | *.ncrunchsolution 39 | *.testlog 40 | testlog.manifest 41 | src/.vs/TinyIoC/DesignTimeBuild/.dtbcache.v2 42 | 43 | .idea/.idea.TinyIoC/.idea/ 44 | 45 | .DS_Store 46 | 47 | artifacts/ 48 | /.vs 49 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2016 Steven Robbins 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build status](https://github.com/grumpydev/TinyIoC/workflows/Build/badge.svg)](https://github.com/grumpydev/TinyIoC/actions) 2 | [![NuGet Version](http://img.shields.io/nuget/v/TinyIoC.svg?style=flat)](https://www.nuget.org/packages/TinyIoC/) 3 | 4 | ## Welcome to TinyIoC 5 | 6 | ### Overview 7 | 8 | Welcome to TinyIoC - an easy to use, hassle free, Inversion of Control Container. TinyIoC has been designed to fulfil a single key requirement - to lower the "level of entry" for using an IoC container; both for small projects, and developers who are new to IoC who might be "scared" of the "big boys"! 9 | 10 | To that end, TinyIoC attempts to stick to the following core principals: 11 | 12 | * **Simplified Inclusion** - No assembly to reference, no binary to worry about, just a single cs file you can include in your project and you're good to go. It even works with both Mono and MonoTouch for iPhone development! 13 | * **Simplified Setup** - With auto-resolving of concrete types and an "auto registration" option for interfaces setup is a piece of cake. It can be reduced to 0 lines for concrete types, or 1 line if you have any interface dependencies! 14 | * **Simple, "Fluent" API** - Just because it's "Tiny", doesn't mean it has no features. A simple "fluent" API gives you access to the more advanced features, like specifying singleton/multi-instance, strong or weak references or forcing a particular constructor. 15 | 16 | In addition to this, TinyIoC's "simplified inclusion" makes it useful for providing DI for internal library classes, or providing your library the ability to use DI without the consuming developer having to specify a container (although it's useful to provide the option to do so). 17 | 18 | **Note** For ASP.Net per-request lifetime support you will need to also include TinyIoCAspNetExtensions.cs, and the TinyIoC namespace. This provides an extension method for supporting per-request registrations. It's an extra file, but it's preferable to taking a dependency on Asp.Net in the main file, which then requires users to setup #DEFINEs for non-asp.net platforms. 19 | 20 | ### Key Features 21 | 22 | * Simple inclusion - just add the CS file (or VB file coming soon!) and off you go. 23 | * Wide platform support - actively tested on Windows, Mono, MonoTouch, PocketPC and Windows Phone 7. Also works just fine on MonoDroid. 24 | * Simple API for Register, Resolve, CanResolve and TryResolve. 25 | * Supports constructor injection and property injection. Constructors are selected automatically but can be overridden using a "fluent" API. 26 | * Lifetime management - including singletons, multi-instance and ASP.Net per-request singletons. 27 | * Automatic lazy factories - a Func dependency will automatically create a factory. 28 | * RegisterMultiple/ResolveAll/IEnumerable support - multiple implementations of an interface can be registered and resolved to an IEnumerable using ResolveAll, or taking a dependency on IEnumerable. 29 | * Child containers - lifetime can be managed using child containers, with automatic "bubbling" of resolving to parent containers where required. 30 | -------------------------------------------------------------------------------- /TinyIoC.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30011.22 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TinyIoC", "src\TinyIoC\TinyIoC.csproj", "{72FF4023-DEDF-40D2-8E54-1BB3E9C38C5C}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TinyIoC.Tests", "tests\TinyIoC.Tests\TinyIoC.Tests.csproj", "{C0F65D37-0DF3-43F6-9338-8FC57453876A}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TinyIoC.Tests.ExternalTypes", "tests\TinyIoC.Tests.ExternalTypes\TinyIoC.Tests.ExternalTypes.csproj", "{F6422C73-C40A-489A-A822-387E3098B2F1}" 11 | EndProject 12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{234A5083-1F24-45B1-9A50-5318A3EC9DFD}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TinyIoC.AspNetExtensions", "src\TinyIoC.AspNetExtensions\TinyIoC.AspNetExtensions.csproj", "{10A02824-B74A-4A2B-905A-486DF703ADA7}" 15 | EndProject 16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TinyMessenger", "src\TinyMessenger\TinyMessenger.csproj", "{C89AD914-7A99-4BFF-B645-AB787FEFC89A}" 17 | EndProject 18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TinyIoc.Benchmarks", "tests\TinyIoc.Benchmarks\TinyIoc.Benchmarks.csproj", "{D8C074F1-4F9F-4E95-B1AC-4D91D98B34D5}" 19 | EndProject 20 | Global 21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 | Debug|Any CPU = Debug|Any CPU 23 | Release|Any CPU = Release|Any CPU 24 | Source|Any CPU = Source|Any CPU 25 | EndGlobalSection 26 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 27 | {72FF4023-DEDF-40D2-8E54-1BB3E9C38C5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 28 | {72FF4023-DEDF-40D2-8E54-1BB3E9C38C5C}.Debug|Any CPU.Build.0 = Debug|Any CPU 29 | {72FF4023-DEDF-40D2-8E54-1BB3E9C38C5C}.Release|Any CPU.ActiveCfg = Release|Any CPU 30 | {72FF4023-DEDF-40D2-8E54-1BB3E9C38C5C}.Release|Any CPU.Build.0 = Release|Any CPU 31 | {72FF4023-DEDF-40D2-8E54-1BB3E9C38C5C}.Source|Any CPU.ActiveCfg = Source|Any CPU 32 | {72FF4023-DEDF-40D2-8E54-1BB3E9C38C5C}.Source|Any CPU.Build.0 = Source|Any CPU 33 | {C0F65D37-0DF3-43F6-9338-8FC57453876A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 34 | {C0F65D37-0DF3-43F6-9338-8FC57453876A}.Debug|Any CPU.Build.0 = Debug|Any CPU 35 | {C0F65D37-0DF3-43F6-9338-8FC57453876A}.Release|Any CPU.ActiveCfg = Release|Any CPU 36 | {C0F65D37-0DF3-43F6-9338-8FC57453876A}.Release|Any CPU.Build.0 = Release|Any CPU 37 | {C0F65D37-0DF3-43F6-9338-8FC57453876A}.Source|Any CPU.ActiveCfg = Release|Any CPU 38 | {C0F65D37-0DF3-43F6-9338-8FC57453876A}.Source|Any CPU.Build.0 = Release|Any CPU 39 | {F6422C73-C40A-489A-A822-387E3098B2F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 40 | {F6422C73-C40A-489A-A822-387E3098B2F1}.Debug|Any CPU.Build.0 = Debug|Any CPU 41 | {F6422C73-C40A-489A-A822-387E3098B2F1}.Release|Any CPU.ActiveCfg = Release|Any CPU 42 | {F6422C73-C40A-489A-A822-387E3098B2F1}.Release|Any CPU.Build.0 = Release|Any CPU 43 | {F6422C73-C40A-489A-A822-387E3098B2F1}.Source|Any CPU.ActiveCfg = Release|Any CPU 44 | {F6422C73-C40A-489A-A822-387E3098B2F1}.Source|Any CPU.Build.0 = Release|Any CPU 45 | {10A02824-B74A-4A2B-905A-486DF703ADA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 46 | {10A02824-B74A-4A2B-905A-486DF703ADA7}.Debug|Any CPU.Build.0 = Debug|Any CPU 47 | {10A02824-B74A-4A2B-905A-486DF703ADA7}.Release|Any CPU.ActiveCfg = Release|Any CPU 48 | {10A02824-B74A-4A2B-905A-486DF703ADA7}.Release|Any CPU.Build.0 = Release|Any CPU 49 | {10A02824-B74A-4A2B-905A-486DF703ADA7}.Source|Any CPU.ActiveCfg = Source|Any CPU 50 | {10A02824-B74A-4A2B-905A-486DF703ADA7}.Source|Any CPU.Build.0 = Source|Any CPU 51 | {C89AD914-7A99-4BFF-B645-AB787FEFC89A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 52 | {C89AD914-7A99-4BFF-B645-AB787FEFC89A}.Debug|Any CPU.Build.0 = Debug|Any CPU 53 | {C89AD914-7A99-4BFF-B645-AB787FEFC89A}.Release|Any CPU.ActiveCfg = Release|Any CPU 54 | {C89AD914-7A99-4BFF-B645-AB787FEFC89A}.Release|Any CPU.Build.0 = Release|Any CPU 55 | {C89AD914-7A99-4BFF-B645-AB787FEFC89A}.Source|Any CPU.ActiveCfg = Source|Any CPU 56 | {C89AD914-7A99-4BFF-B645-AB787FEFC89A}.Source|Any CPU.Build.0 = Source|Any CPU 57 | {D8C074F1-4F9F-4E95-B1AC-4D91D98B34D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 58 | {D8C074F1-4F9F-4E95-B1AC-4D91D98B34D5}.Debug|Any CPU.Build.0 = Debug|Any CPU 59 | {D8C074F1-4F9F-4E95-B1AC-4D91D98B34D5}.Release|Any CPU.ActiveCfg = Release|Any CPU 60 | {D8C074F1-4F9F-4E95-B1AC-4D91D98B34D5}.Release|Any CPU.Build.0 = Release|Any CPU 61 | {D8C074F1-4F9F-4E95-B1AC-4D91D98B34D5}.Source|Any CPU.ActiveCfg = Debug|Any CPU 62 | {D8C074F1-4F9F-4E95-B1AC-4D91D98B34D5}.Source|Any CPU.Build.0 = Debug|Any CPU 63 | EndGlobalSection 64 | GlobalSection(SolutionProperties) = preSolution 65 | HideSolutionNode = FALSE 66 | EndGlobalSection 67 | GlobalSection(NestedProjects) = preSolution 68 | {C0F65D37-0DF3-43F6-9338-8FC57453876A} = {234A5083-1F24-45B1-9A50-5318A3EC9DFD} 69 | {F6422C73-C40A-489A-A822-387E3098B2F1} = {234A5083-1F24-45B1-9A50-5318A3EC9DFD} 70 | {D8C074F1-4F9F-4E95-B1AC-4D91D98B34D5} = {234A5083-1F24-45B1-9A50-5318A3EC9DFD} 71 | EndGlobalSection 72 | GlobalSection(ExtensibilityGlobals) = postSolution 73 | SolutionGuid = {A25E106A-01ED-4DE8-8278-A216350EE569} 74 | EndGlobalSection 75 | EndGlobal 76 | -------------------------------------------------------------------------------- /build/TinyIoC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grumpydev/TinyIoC/49889ccf0d1e50510700319380109566a72047cc/build/TinyIoC.png -------------------------------------------------------------------------------- /build/TinyIoC.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grumpydev/TinyIoC/49889ccf0d1e50510700319380109566a72047cc/build/TinyIoC.psd -------------------------------------------------------------------------------- /build/common.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | TinyIoC 5 | Steven Robbins 6 | Andy Sherwood, Steven Robbins, Blake Niemyjski 7 | An easy to use, hassle free, Inversion of Control Container for small projects, libraries and beginners alike 8 | https://github.com/grumpydev/TinyIoC 9 | https://github.com/grumpydev/TinyIoC/releases 10 | IoC 11 | Source;Debug;Release 12 | true 13 | 14 | 15 | true 16 | $(NoWarn);CS1591;NU1701;CS8021 17 | true 18 | latest 19 | true 20 | $(SolutionDir)artifacts 21 | TinyIoC.png 22 | LICENSE.txt 23 | $(PackageProjectUrl) 24 | true 25 | false 26 | false 27 | Library 28 | 29 | 30 | 31 | false 32 | true 33 | CS8021 34 | false 35 | Content 36 | true 37 | false 38 | false 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30011.22 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MvcTestApplication", "MvcTestApplication\MvcTestApplication.csproj", "{2658E893-EB33-43FE-B4D0-AD16BC76578B}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {2658E893-EB33-43FE-B4D0-AD16BC76578B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {2658E893-EB33-43FE-B4D0-AD16BC76578B}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {2658E893-EB33-43FE-B4D0-AD16BC76578B}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {2658E893-EB33-43FE-B4D0-AD16BC76578B}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {9288D4A6-BBEC-4995-89CE-5E5AC37851B4} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/ApplicationDependencyClass.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MvcTestApplication 4 | { 5 | public class ApplicationDependencyClass : IApplicationDependency 6 | { 7 | private readonly DateTime _CurrentDateTime; 8 | 9 | /// 10 | /// Initializes a new instance of the RequestDependencyClass class. 11 | /// 12 | public ApplicationDependencyClass() 13 | { 14 | _CurrentDateTime = DateTime.Now; 15 | } 16 | 17 | public string GetContent() 18 | { 19 | return "This is an application level dependency, constructed on: " + _CurrentDateTime.ToLongTimeString(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/Content/Site.css: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------- 2 | The base color for this template is #5c87b2. If you'd like 3 | to use a different color start by replacing all instances of 4 | #5c87b2 with your new color. 5 | ----------------------------------------------------------*/ 6 | body 7 | { 8 | background-color: #5c87b2; 9 | font-size: .75em; 10 | font-family: Verdana, Helvetica, Sans-Serif; 11 | margin: 0; 12 | padding: 0; 13 | color: #696969; 14 | } 15 | 16 | a:link 17 | { 18 | color: #034af3; 19 | text-decoration: underline; 20 | } 21 | a:visited 22 | { 23 | color: #505abc; 24 | } 25 | a:hover 26 | { 27 | color: #1d60ff; 28 | text-decoration: none; 29 | } 30 | a:active 31 | { 32 | color: #12eb87; 33 | } 34 | 35 | p, ul 36 | { 37 | margin-bottom: 20px; 38 | line-height: 1.6em; 39 | } 40 | 41 | /* HEADINGS 42 | ----------------------------------------------------------*/ 43 | h1, h2, h3, h4, h5, h6 44 | { 45 | font-size: 1.5em; 46 | color: #000; 47 | font-family: Arial, Helvetica, sans-serif; 48 | } 49 | 50 | h1 51 | { 52 | font-size: 2em; 53 | padding-bottom: 0; 54 | margin-bottom: 0; 55 | } 56 | h2 57 | { 58 | padding: 0 0 10px 0; 59 | } 60 | h3 61 | { 62 | font-size: 1.2em; 63 | } 64 | h4 65 | { 66 | font-size: 1.1em; 67 | } 68 | h5, h6 69 | { 70 | font-size: 1em; 71 | } 72 | 73 | /* this rule styles

tags that are the 74 | first child of the left and right table columns */ 75 | .rightColumn > h1, .rightColumn > h2, .leftColumn > h1, .leftColumn > h2 76 | { 77 | margin-top: 0; 78 | } 79 | 80 | /* PRIMARY LAYOUT ELEMENTS 81 | ----------------------------------------------------------*/ 82 | 83 | /* you can specify a greater or lesser percentage for the 84 | page width. Or, you can specify an exact pixel width. */ 85 | .page 86 | { 87 | width: 90%; 88 | margin-left: auto; 89 | margin-right: auto; 90 | } 91 | 92 | #header 93 | { 94 | position: relative; 95 | margin-bottom: 0px; 96 | color: #000; 97 | padding: 0; 98 | } 99 | 100 | #header h1 101 | { 102 | font-weight: bold; 103 | padding: 5px 0; 104 | margin: 0; 105 | color: #fff; 106 | border: none; 107 | line-height: 2em; 108 | font-family: Arial, Helvetica, sans-serif; 109 | font-size: 32px !important; 110 | } 111 | 112 | #main 113 | { 114 | padding: 30px 30px 15px 30px; 115 | background-color: #fff; 116 | margin-bottom: 30px; 117 | _height: 1px; /* only IE6 applies CSS properties starting with an underscore */ 118 | } 119 | 120 | #footer 121 | { 122 | color: #999; 123 | padding: 10px 0; 124 | text-align: center; 125 | line-height: normal; 126 | margin: 0; 127 | font-size: .9em; 128 | } 129 | 130 | /* TAB MENU 131 | ----------------------------------------------------------*/ 132 | ul#menu 133 | { 134 | border-bottom: 1px #5C87B2 solid; 135 | padding: 0 0 2px; 136 | position: relative; 137 | margin: 0; 138 | text-align: right; 139 | } 140 | 141 | ul#menu li 142 | { 143 | display: inline; 144 | list-style: none; 145 | } 146 | 147 | ul#menu li#greeting 148 | { 149 | padding: 10px 20px; 150 | font-weight: bold; 151 | text-decoration: none; 152 | line-height: 2.8em; 153 | color: #fff; 154 | } 155 | 156 | ul#menu li a 157 | { 158 | padding: 10px 20px; 159 | font-weight: bold; 160 | text-decoration: none; 161 | line-height: 2.8em; 162 | background-color: #e8eef4; 163 | color: #034af3; 164 | } 165 | 166 | ul#menu li a:hover 167 | { 168 | background-color: #fff; 169 | text-decoration: none; 170 | } 171 | 172 | ul#menu li a:active 173 | { 174 | background-color: #a6e2a6; 175 | text-decoration: none; 176 | } 177 | 178 | ul#menu li.selected a 179 | { 180 | background-color: #fff; 181 | color: #000; 182 | } 183 | 184 | /* FORM LAYOUT ELEMENTS 185 | ----------------------------------------------------------*/ 186 | 187 | fieldset 188 | { 189 | margin: 1em 0; 190 | padding: 1em; 191 | border: 1px solid #CCC; 192 | } 193 | 194 | fieldset p 195 | { 196 | margin: 2px 12px 10px 10px; 197 | } 198 | 199 | legend 200 | { 201 | font-size: 1.1em; 202 | font-weight: 600; 203 | padding: 2px 4px 8px 4px; 204 | } 205 | 206 | input[type="text"] 207 | { 208 | width: 200px; 209 | border: 1px solid #CCC; 210 | } 211 | 212 | input[type="password"] 213 | { 214 | width: 200px; 215 | border: 1px solid #CCC; 216 | } 217 | 218 | /* TABLE 219 | ----------------------------------------------------------*/ 220 | 221 | table 222 | { 223 | border: solid 1px #e8eef4; 224 | border-collapse: collapse; 225 | } 226 | 227 | table td 228 | { 229 | padding: 5px; 230 | border: solid 1px #e8eef4; 231 | } 232 | 233 | table th 234 | { 235 | padding: 6px 5px; 236 | text-align: left; 237 | background-color: #e8eef4; 238 | border: solid 1px #e8eef4; 239 | } 240 | 241 | /* MISC 242 | ----------------------------------------------------------*/ 243 | .clear 244 | { 245 | clear: both; 246 | } 247 | 248 | .error 249 | { 250 | color:Red; 251 | } 252 | 253 | #menucontainer 254 | { 255 | margin-top:40px; 256 | } 257 | 258 | div#title 259 | { 260 | display:block; 261 | float:left; 262 | text-align:left; 263 | } 264 | 265 | #logindisplay 266 | { 267 | font-size:1.1em; 268 | display:block; 269 | text-align:right; 270 | margin:10px; 271 | color:White; 272 | } 273 | 274 | #logindisplay a:link 275 | { 276 | color: white; 277 | text-decoration: underline; 278 | } 279 | 280 | #logindisplay a:visited 281 | { 282 | color: white; 283 | text-decoration: underline; 284 | } 285 | 286 | #logindisplay a:hover 287 | { 288 | color: white; 289 | text-decoration: none; 290 | } 291 | 292 | /* Styles for validation helpers 293 | -----------------------------------------------------------*/ 294 | .field-validation-error 295 | { 296 | color: #ff0000; 297 | } 298 | 299 | .field-validation-valid 300 | { 301 | display: none; 302 | } 303 | 304 | .input-validation-error 305 | { 306 | border: 1px solid #ff0000; 307 | background-color: #ffeeee; 308 | } 309 | 310 | .validation-summary-errors 311 | { 312 | font-weight: bold; 313 | color: #ff0000; 314 | } 315 | 316 | .validation-summary-valid 317 | { 318 | display: none; 319 | } 320 | 321 | /* Styles for editor and display helpers 322 | ----------------------------------------------------------*/ 323 | .display-label, 324 | .editor-label, 325 | .display-field, 326 | .editor-field 327 | { 328 | margin: 0.5em 0; 329 | } 330 | 331 | .text-box 332 | { 333 | width: 30em; 334 | } 335 | 336 | .text-box.multi-line 337 | { 338 | height: 6.5em; 339 | } 340 | 341 | .tri-state 342 | { 343 | width: 6em; 344 | } 345 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/Controllers/AccountController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics.CodeAnalysis; 4 | using System.Linq; 5 | using System.Security.Principal; 6 | using System.Web; 7 | using System.Web.Mvc; 8 | using System.Web.Routing; 9 | using System.Web.Security; 10 | using MvcTestApplication.Models; 11 | 12 | namespace MvcTestApplication.Controllers 13 | { 14 | 15 | [HandleError] 16 | public class AccountController : Controller 17 | { 18 | 19 | public IFormsAuthenticationService FormsService { get; set; } 20 | public IMembershipService MembershipService { get; set; } 21 | 22 | protected override void Initialize(RequestContext requestContext) 23 | { 24 | if (FormsService == null) { FormsService = new FormsAuthenticationService(); } 25 | if (MembershipService == null) { MembershipService = new AccountMembershipService(); } 26 | 27 | base.Initialize(requestContext); 28 | } 29 | 30 | // ************************************** 31 | // URL: /Account/LogOn 32 | // ************************************** 33 | 34 | public ActionResult LogOn() 35 | { 36 | return View(); 37 | } 38 | 39 | [HttpPost] 40 | public ActionResult LogOn(LogOnModel model, string returnUrl) 41 | { 42 | if (ModelState.IsValid) 43 | { 44 | if (MembershipService.ValidateUser(model.UserName, model.Password)) 45 | { 46 | FormsService.SignIn(model.UserName, model.RememberMe); 47 | if (!String.IsNullOrEmpty(returnUrl)) 48 | { 49 | return Redirect(returnUrl); 50 | } 51 | else 52 | { 53 | return RedirectToAction("Index", "Home"); 54 | } 55 | } 56 | else 57 | { 58 | ModelState.AddModelError("", "The user name or password provided is incorrect."); 59 | } 60 | } 61 | 62 | // If we got this far, something failed, redisplay form 63 | return View(model); 64 | } 65 | 66 | // ************************************** 67 | // URL: /Account/LogOff 68 | // ************************************** 69 | 70 | public ActionResult LogOff() 71 | { 72 | FormsService.SignOut(); 73 | 74 | return RedirectToAction("Index", "Home"); 75 | } 76 | 77 | // ************************************** 78 | // URL: /Account/Register 79 | // ************************************** 80 | 81 | public ActionResult Register() 82 | { 83 | ViewData["PasswordLength"] = MembershipService.MinPasswordLength; 84 | return View(); 85 | } 86 | 87 | [HttpPost] 88 | public ActionResult Register(RegisterModel model) 89 | { 90 | if (ModelState.IsValid) 91 | { 92 | // Attempt to register the user 93 | MembershipCreateStatus createStatus = MembershipService.CreateUser(model.UserName, model.Password, model.Email); 94 | 95 | if (createStatus == MembershipCreateStatus.Success) 96 | { 97 | FormsService.SignIn(model.UserName, false /* createPersistentCookie */); 98 | return RedirectToAction("Index", "Home"); 99 | } 100 | else 101 | { 102 | ModelState.AddModelError("", AccountValidation.ErrorCodeToString(createStatus)); 103 | } 104 | } 105 | 106 | // If we got this far, something failed, redisplay form 107 | ViewData["PasswordLength"] = MembershipService.MinPasswordLength; 108 | return View(model); 109 | } 110 | 111 | // ************************************** 112 | // URL: /Account/ChangePassword 113 | // ************************************** 114 | 115 | [Authorize] 116 | public ActionResult ChangePassword() 117 | { 118 | ViewData["PasswordLength"] = MembershipService.MinPasswordLength; 119 | return View(); 120 | } 121 | 122 | [Authorize] 123 | [HttpPost] 124 | public ActionResult ChangePassword(ChangePasswordModel model) 125 | { 126 | if (ModelState.IsValid) 127 | { 128 | if (MembershipService.ChangePassword(User.Identity.Name, model.OldPassword, model.NewPassword)) 129 | { 130 | return RedirectToAction("ChangePasswordSuccess"); 131 | } 132 | else 133 | { 134 | ModelState.AddModelError("", "The current password is incorrect or the new password is invalid."); 135 | } 136 | } 137 | 138 | // If we got this far, something failed, redisplay form 139 | ViewData["PasswordLength"] = MembershipService.MinPasswordLength; 140 | return View(model); 141 | } 142 | 143 | // ************************************** 144 | // URL: /Account/ChangePasswordSuccess 145 | // ************************************** 146 | 147 | public ActionResult ChangePasswordSuccess() 148 | { 149 | return View(); 150 | } 151 | 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using System.Threading; 7 | 8 | namespace MvcTestApplication.Controllers 9 | { 10 | [HandleError] 11 | public class HomeController : Controller 12 | { 13 | public ActionResult Index() 14 | { 15 | // Service location just to prove it works :-) 16 | var container = TinyIoC.TinyIoCContainer.Current; 17 | var applicationObject = container.Resolve(); 18 | var requestObject = container.Resolve(); 19 | // Just to the time increments :-) 20 | Thread.Sleep(2000); 21 | var requestObject2 = container.Resolve(); 22 | 23 | ViewData["Message"] = "Welcome to ASP.NET MVC!"; 24 | ViewData["ApplicationMessage"] = applicationObject.GetContent(); 25 | ViewData["RequestMessage"] = requestObject.GetContent(); 26 | ViewData["RequestMessage2"] = requestObject2.GetContent(); 27 | ViewData["ResultMessage"] = String.Format("Both request dependencies are the same instance: {0}", object.ReferenceEquals(requestObject, requestObject2)); 28 | 29 | return View(); 30 | } 31 | 32 | public ActionResult About() 33 | { 34 | return View(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="MvcTestApplication.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using System.Web.Routing; 7 | using TinyIoC; 8 | 9 | namespace MvcTestApplication 10 | { 11 | // Note: For instructions on enabling IIS6 or IIS7 classic mode, 12 | // visit http://go.microsoft.com/?LinkId=9394801 13 | 14 | public class MvcApplication : System.Web.HttpApplication 15 | { 16 | public static void RegisterRoutes(RouteCollection routes) 17 | { 18 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 19 | 20 | routes.MapRoute( 21 | "Default", // Route name 22 | "{controller}/{action}/{id}", // URL with parameters 23 | new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 24 | ); 25 | 26 | } 27 | 28 | protected void Application_Start() 29 | { 30 | AreaRegistration.RegisterAllAreas(); 31 | 32 | RegisterRoutes(RouteTable.Routes); 33 | 34 | var container = TinyIoC.TinyIoCContainer.Current; 35 | container.Register().AsSingleton(); 36 | container.Register().AsPerRequestSingleton(); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/IApplicationDependency.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MvcTestApplication 4 | { 5 | public interface IApplicationDependency 6 | { 7 | string GetContent(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/IRequestDependency.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MvcTestApplication 4 | { 5 | public interface IRequestDependency 6 | { 7 | string GetContent(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/Models/AccountModels.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Globalization; 6 | using System.Linq; 7 | using System.Web; 8 | using System.Web.Mvc; 9 | using System.Web.Security; 10 | 11 | namespace MvcTestApplication.Models 12 | { 13 | 14 | #region Models 15 | [PropertiesMustMatch("NewPassword", "ConfirmPassword", ErrorMessage = "The new password and confirmation password do not match.")] 16 | public class ChangePasswordModel 17 | { 18 | [Required] 19 | [DataType(DataType.Password)] 20 | [DisplayName("Current password")] 21 | public string OldPassword { get; set; } 22 | 23 | [Required] 24 | [ValidatePasswordLength] 25 | [DataType(DataType.Password)] 26 | [DisplayName("New password")] 27 | public string NewPassword { get; set; } 28 | 29 | [Required] 30 | [DataType(DataType.Password)] 31 | [DisplayName("Confirm new password")] 32 | public string ConfirmPassword { get; set; } 33 | } 34 | 35 | public class LogOnModel 36 | { 37 | [Required] 38 | [DisplayName("User name")] 39 | public string UserName { get; set; } 40 | 41 | [Required] 42 | [DataType(DataType.Password)] 43 | [DisplayName("Password")] 44 | public string Password { get; set; } 45 | 46 | [DisplayName("Remember me?")] 47 | public bool RememberMe { get; set; } 48 | } 49 | 50 | [PropertiesMustMatch("Password", "ConfirmPassword", ErrorMessage = "The password and confirmation password do not match.")] 51 | public class RegisterModel 52 | { 53 | [Required] 54 | [DisplayName("User name")] 55 | public string UserName { get; set; } 56 | 57 | [Required] 58 | [DataType(DataType.EmailAddress)] 59 | [DisplayName("Email address")] 60 | public string Email { get; set; } 61 | 62 | [Required] 63 | [ValidatePasswordLength] 64 | [DataType(DataType.Password)] 65 | [DisplayName("Password")] 66 | public string Password { get; set; } 67 | 68 | [Required] 69 | [DataType(DataType.Password)] 70 | [DisplayName("Confirm password")] 71 | public string ConfirmPassword { get; set; } 72 | } 73 | #endregion 74 | 75 | #region Services 76 | // The FormsAuthentication type is sealed and contains static members, so it is difficult to 77 | // unit test code that calls its members. The interface and helper class below demonstrate 78 | // how to create an abstract wrapper around such a type in order to make the AccountController 79 | // code unit testable. 80 | 81 | public interface IMembershipService 82 | { 83 | int MinPasswordLength { get; } 84 | 85 | bool ValidateUser(string userName, string password); 86 | MembershipCreateStatus CreateUser(string userName, string password, string email); 87 | bool ChangePassword(string userName, string oldPassword, string newPassword); 88 | } 89 | 90 | public class AccountMembershipService : IMembershipService 91 | { 92 | private readonly MembershipProvider _provider; 93 | 94 | public AccountMembershipService() 95 | : this(null) 96 | { 97 | } 98 | 99 | public AccountMembershipService(MembershipProvider provider) 100 | { 101 | _provider = provider ?? Membership.Provider; 102 | } 103 | 104 | public int MinPasswordLength 105 | { 106 | get 107 | { 108 | return _provider.MinRequiredPasswordLength; 109 | } 110 | } 111 | 112 | public bool ValidateUser(string userName, string password) 113 | { 114 | if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName"); 115 | if (String.IsNullOrEmpty(password)) throw new ArgumentException("Value cannot be null or empty.", "password"); 116 | 117 | return _provider.ValidateUser(userName, password); 118 | } 119 | 120 | public MembershipCreateStatus CreateUser(string userName, string password, string email) 121 | { 122 | if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName"); 123 | if (String.IsNullOrEmpty(password)) throw new ArgumentException("Value cannot be null or empty.", "password"); 124 | if (String.IsNullOrEmpty(email)) throw new ArgumentException("Value cannot be null or empty.", "email"); 125 | 126 | MembershipCreateStatus status; 127 | _provider.CreateUser(userName, password, email, null, null, true, null, out status); 128 | return status; 129 | } 130 | 131 | public bool ChangePassword(string userName, string oldPassword, string newPassword) 132 | { 133 | if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName"); 134 | if (String.IsNullOrEmpty(oldPassword)) throw new ArgumentException("Value cannot be null or empty.", "oldPassword"); 135 | if (String.IsNullOrEmpty(newPassword)) throw new ArgumentException("Value cannot be null or empty.", "newPassword"); 136 | 137 | // The underlying ChangePassword() will throw an exception rather 138 | // than return false in certain failure scenarios. 139 | try 140 | { 141 | MembershipUser currentUser = _provider.GetUser(userName, true /* userIsOnline */); 142 | return currentUser.ChangePassword(oldPassword, newPassword); 143 | } 144 | catch (ArgumentException) 145 | { 146 | return false; 147 | } 148 | catch (MembershipPasswordException) 149 | { 150 | return false; 151 | } 152 | } 153 | } 154 | 155 | public interface IFormsAuthenticationService 156 | { 157 | void SignIn(string userName, bool createPersistentCookie); 158 | void SignOut(); 159 | } 160 | 161 | public class FormsAuthenticationService : IFormsAuthenticationService 162 | { 163 | public void SignIn(string userName, bool createPersistentCookie) 164 | { 165 | if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName"); 166 | 167 | FormsAuthentication.SetAuthCookie(userName, createPersistentCookie); 168 | } 169 | 170 | public void SignOut() 171 | { 172 | FormsAuthentication.SignOut(); 173 | } 174 | } 175 | #endregion 176 | 177 | #region Validation 178 | public static class AccountValidation 179 | { 180 | public static string ErrorCodeToString(MembershipCreateStatus createStatus) 181 | { 182 | // See http://go.microsoft.com/fwlink/?LinkID=177550 for 183 | // a full list of status codes. 184 | switch (createStatus) 185 | { 186 | case MembershipCreateStatus.DuplicateUserName: 187 | return "Username already exists. Please enter a different user name."; 188 | 189 | case MembershipCreateStatus.DuplicateEmail: 190 | return "A username for that e-mail address already exists. Please enter a different e-mail address."; 191 | 192 | case MembershipCreateStatus.InvalidPassword: 193 | return "The password provided is invalid. Please enter a valid password value."; 194 | 195 | case MembershipCreateStatus.InvalidEmail: 196 | return "The e-mail address provided is invalid. Please check the value and try again."; 197 | 198 | case MembershipCreateStatus.InvalidAnswer: 199 | return "The password retrieval answer provided is invalid. Please check the value and try again."; 200 | 201 | case MembershipCreateStatus.InvalidQuestion: 202 | return "The password retrieval question provided is invalid. Please check the value and try again."; 203 | 204 | case MembershipCreateStatus.InvalidUserName: 205 | return "The user name provided is invalid. Please check the value and try again."; 206 | 207 | case MembershipCreateStatus.ProviderError: 208 | return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator."; 209 | 210 | case MembershipCreateStatus.UserRejected: 211 | return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator."; 212 | 213 | default: 214 | return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator."; 215 | } 216 | } 217 | } 218 | 219 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] 220 | public sealed class PropertiesMustMatchAttribute : ValidationAttribute 221 | { 222 | private const string _defaultErrorMessage = "'{0}' and '{1}' do not match."; 223 | private readonly object _typeId = new object(); 224 | 225 | public PropertiesMustMatchAttribute(string originalProperty, string confirmProperty) 226 | : base(_defaultErrorMessage) 227 | { 228 | OriginalProperty = originalProperty; 229 | ConfirmProperty = confirmProperty; 230 | } 231 | 232 | public string ConfirmProperty { get; private set; } 233 | public string OriginalProperty { get; private set; } 234 | 235 | public override object TypeId 236 | { 237 | get 238 | { 239 | return _typeId; 240 | } 241 | } 242 | 243 | public override string FormatErrorMessage(string name) 244 | { 245 | return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString, 246 | OriginalProperty, ConfirmProperty); 247 | } 248 | 249 | public override bool IsValid(object value) 250 | { 251 | PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value); 252 | object originalValue = properties.Find(OriginalProperty, true /* ignoreCase */).GetValue(value); 253 | object confirmValue = properties.Find(ConfirmProperty, true /* ignoreCase */).GetValue(value); 254 | return Object.Equals(originalValue, confirmValue); 255 | } 256 | } 257 | 258 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)] 259 | public sealed class ValidatePasswordLengthAttribute : ValidationAttribute 260 | { 261 | private const string _defaultErrorMessage = "'{0}' must be at least {1} characters long."; 262 | private readonly int _minCharacters = Membership.Provider.MinRequiredPasswordLength; 263 | 264 | public ValidatePasswordLengthAttribute() 265 | : base(_defaultErrorMessage) 266 | { 267 | } 268 | 269 | public override string FormatErrorMessage(string name) 270 | { 271 | return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString, 272 | name, _minCharacters); 273 | } 274 | 275 | public override bool IsValid(object value) 276 | { 277 | string valueAsString = value as string; 278 | return (valueAsString != null && valueAsString.Length >= _minCharacters); 279 | } 280 | } 281 | #endregion 282 | 283 | } 284 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/MvcTestApplication.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Debug 7 | AnyCPU 8 | 9 | 10 | 2.0 11 | {2658E893-EB33-43FE-B4D0-AD16BC76578B} 12 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} 13 | Library 14 | Properties 15 | MvcTestApplication 16 | MvcTestApplication 17 | v4.7.2 18 | false 19 | false 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | true 29 | full 30 | false 31 | bin\ 32 | DEBUG;TRACE 33 | prompt 34 | 4 35 | 36 | 37 | pdbonly 38 | true 39 | bin\ 40 | TRACE 41 | prompt 42 | 4 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | True 66 | ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll 67 | 68 | 69 | 70 | 71 | 72 | 73 | True 74 | ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.Helpers.dll 75 | 76 | 77 | True 78 | ..\packages\Microsoft.AspNet.Mvc.5.2.7\lib\net45\System.Web.Mvc.dll 79 | 80 | 81 | True 82 | ..\packages\Microsoft.AspNet.Razor.3.2.7\lib\net45\System.Web.Razor.dll 83 | 84 | 85 | True 86 | ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.dll 87 | 88 | 89 | True 90 | ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Deployment.dll 91 | 92 | 93 | True 94 | ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Razor.dll 95 | 96 | 97 | 98 | 99 | ..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll 100 | 101 | 102 | 103 | 104 | TinyIoC\TinyIoC.cs 105 | 106 | 107 | TinyIoC\TinyIoCAspNetExtensions.cs 108 | 109 | 110 | 111 | 112 | 113 | Global.asax 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | Web.config 126 | 127 | 128 | Web.config 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 10.0 151 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | False 164 | True 165 | 49164 166 | / 167 | 168 | 169 | False 170 | False 171 | 172 | 173 | False 174 | 175 | 176 | 177 | 178 | 179 | 180 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/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("MvcTestApplication")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("MvcTestApplication")] 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("efde8126-12b1-42de-b2a6-b00253d1f2b3")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/RequestDependencyClass.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MvcTestApplication 4 | { 5 | public class RequestDependencyClass : IRequestDependency 6 | { 7 | private readonly DateTime _CurrentDateTime; 8 | 9 | /// 10 | /// Initializes a new instance of the RequestDependencyClass class. 11 | /// 12 | public RequestDependencyClass() 13 | { 14 | _CurrentDateTime = DateTime.Now; 15 | } 16 | 17 | public string GetContent() 18 | { 19 | return "This is a per-request dependency, constructed on: " + _CurrentDateTime.ToLongTimeString(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/Views/Account/ChangePassword.aspx: -------------------------------------------------------------------------------- 1 | <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %> 2 | 3 | 4 | Change Password 5 | 6 | 7 | 8 |

Change Password

9 |

10 | Use the form below to change your password. 11 |

12 |

13 | New passwords are required to be a minimum of <%: ViewData["PasswordLength"] %> characters in length. 14 |

15 | 16 | <% using (Html.BeginForm()) { %> 17 | <%: Html.ValidationSummary(true, "Password change was unsuccessful. Please correct the errors and try again.") %> 18 |
19 |
20 | Account Information 21 | 22 |
23 | <%: Html.LabelFor(m => m.OldPassword) %> 24 |
25 |
26 | <%: Html.PasswordFor(m => m.OldPassword) %> 27 | <%: Html.ValidationMessageFor(m => m.OldPassword) %> 28 |
29 | 30 |
31 | <%: Html.LabelFor(m => m.NewPassword) %> 32 |
33 |
34 | <%: Html.PasswordFor(m => m.NewPassword) %> 35 | <%: Html.ValidationMessageFor(m => m.NewPassword) %> 36 |
37 | 38 |
39 | <%: Html.LabelFor(m => m.ConfirmPassword) %> 40 |
41 |
42 | <%: Html.PasswordFor(m => m.ConfirmPassword) %> 43 | <%: Html.ValidationMessageFor(m => m.ConfirmPassword) %> 44 |
45 | 46 |

47 | 48 |

49 |
50 |
51 | <% } %> 52 |
53 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/Views/Account/ChangePasswordSuccess.aspx: -------------------------------------------------------------------------------- 1 | <%@Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %> 2 | 3 | 4 | Change Password 5 | 6 | 7 | 8 |

Change Password

9 |

10 | Your password has been changed successfully. 11 |

12 |
13 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/Views/Account/LogOn.aspx: -------------------------------------------------------------------------------- 1 | <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %> 2 | 3 | 4 | Log On 5 | 6 | 7 | 8 |

Log On

9 |

10 | Please enter your username and password. <%: Html.ActionLink("Register", "Register") %> if you don't have an account. 11 |

12 | 13 | <% using (Html.BeginForm()) { %> 14 | <%: Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.") %> 15 |
16 |
17 | Account Information 18 | 19 |
20 | <%: Html.LabelFor(m => m.UserName) %> 21 |
22 |
23 | <%: Html.TextBoxFor(m => m.UserName) %> 24 | <%: Html.ValidationMessageFor(m => m.UserName) %> 25 |
26 | 27 |
28 | <%: Html.LabelFor(m => m.Password) %> 29 |
30 |
31 | <%: Html.PasswordFor(m => m.Password) %> 32 | <%: Html.ValidationMessageFor(m => m.Password) %> 33 |
34 | 35 |
36 | <%: Html.CheckBoxFor(m => m.RememberMe) %> 37 | <%: Html.LabelFor(m => m.RememberMe) %> 38 |
39 | 40 |

41 | 42 |

43 |
44 |
45 | <% } %> 46 |
47 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/Views/Account/Register.aspx: -------------------------------------------------------------------------------- 1 | <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %> 2 | 3 | 4 | Register 5 | 6 | 7 | 8 |

Create a New Account

9 |

10 | Use the form below to create a new account. 11 |

12 |

13 | Passwords are required to be a minimum of <%: ViewData["PasswordLength"] %> characters in length. 14 |

15 | 16 | <% using (Html.BeginForm()) { %> 17 | <%: Html.ValidationSummary(true, "Account creation was unsuccessful. Please correct the errors and try again.") %> 18 |
19 |
20 | Account Information 21 | 22 |
23 | <%: Html.LabelFor(m => m.UserName) %> 24 |
25 |
26 | <%: Html.TextBoxFor(m => m.UserName) %> 27 | <%: Html.ValidationMessageFor(m => m.UserName) %> 28 |
29 | 30 |
31 | <%: Html.LabelFor(m => m.Email) %> 32 |
33 |
34 | <%: Html.TextBoxFor(m => m.Email) %> 35 | <%: Html.ValidationMessageFor(m => m.Email) %> 36 |
37 | 38 |
39 | <%: Html.LabelFor(m => m.Password) %> 40 |
41 |
42 | <%: Html.PasswordFor(m => m.Password) %> 43 | <%: Html.ValidationMessageFor(m => m.Password) %> 44 |
45 | 46 |
47 | <%: Html.LabelFor(m => m.ConfirmPassword) %> 48 |
49 |
50 | <%: Html.PasswordFor(m => m.ConfirmPassword) %> 51 | <%: Html.ValidationMessageFor(m => m.ConfirmPassword) %> 52 |
53 | 54 |

55 | 56 |

57 |
58 |
59 | <% } %> 60 |
61 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/Views/Home/About.aspx: -------------------------------------------------------------------------------- 1 | <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %> 2 | 3 | 4 | About Us 5 | 6 | 7 | 8 |

About

9 |

10 | Put content here. 11 |

12 |
13 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/Views/Home/Index.aspx: -------------------------------------------------------------------------------- 1 | <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %> 2 | 3 | 4 | Home Page 5 | 6 | 7 | 8 |

<%: ViewData["Message"] %>

9 |

10 | <%: ViewData["ApplicationMessage"] %> 11 |

12 |

13 | <%: ViewData["RequestMessage"] %> 14 |

15 |

.. big pause ..

16 |

17 | <%: ViewData["RequestMessage2"] %> 18 |

19 |

20 | <%: ViewData["ResultMessage"]%> 21 |

22 | 23 |
24 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/Views/Shared/Error.aspx: -------------------------------------------------------------------------------- 1 | <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %> 2 | 3 | 4 | Error 5 | 6 | 7 | 8 |

9 | Sorry, an error occurred while processing your request. 10 |

11 |
12 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/Views/Shared/LogOnUserControl.ascx: -------------------------------------------------------------------------------- 1 | <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> 2 | <% 3 | if (Request.IsAuthenticated) { 4 | %> 5 | Welcome <%: Page.User.Identity.Name %>! 6 | [ <%: Html.ActionLink("Log Off", "LogOff", "Account") %> ] 7 | <% 8 | } 9 | else { 10 | %> 11 | [ <%: Html.ActionLink("Log On", "LogOn", "Account") %> ] 12 | <% 13 | } 14 | %> 15 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/Views/Shared/Site.Master: -------------------------------------------------------------------------------- 1 | <%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %> 2 | 3 | 4 | 5 | 6 | <asp:ContentPlaceHolder ID="TitleContent" runat="server" /> 7 | 8 | 9 | 10 | 11 |
12 | 13 | 31 | 32 |
33 | 34 | 35 | 37 |
38 |
39 | 40 | 41 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/Views/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 16 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/Web.Debug.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/Web.Release.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/Web.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 | 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 | 74 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /samples/ASPNet/MvcTestApplication/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/TinyIoC.AspNetExtensions/TinyIoC.AspNetExtensions.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | netstandard2.0;net45 8 | 9 | 10 | 11 | $(DefineConstants);NETSTANDARD;NETSTANDARD2_0 12 | 13 | 14 | 15 | IoC,ASPNET 16 | 17 | 18 | 19 | 20 | 21 | 3.5 22 | 23 | 24 | 25 | 3.5 26 | 27 | 28 | 3.5 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | true 44 | true 45 | contentFiles/cs/any 46 | 47 | 48 | true 49 | true 50 | content 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/TinyIoC.AspNetExtensions/TinyIoCAspNetExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web; 3 | 4 | namespace TinyIoC 5 | { 6 | #if TINYIOC_INTERNAL 7 | internal 8 | #else 9 | public 10 | #endif 11 | class HttpContextLifetimeProvider : TinyIoCContainer.ITinyIoCObjectLifetimeProvider 12 | { 13 | private readonly string _KeyName = String.Format("TinyIoC.HttpContext.{0}", Guid.NewGuid()); 14 | 15 | public object GetObject() 16 | { 17 | return HttpContext.Current.Items[_KeyName]; 18 | } 19 | 20 | public void SetObject(object value) 21 | { 22 | HttpContext.Current.Items[_KeyName] = value; 23 | } 24 | 25 | public void ReleaseObject() 26 | { 27 | var item = GetObject() as IDisposable; 28 | 29 | if (item != null) 30 | item.Dispose(); 31 | 32 | SetObject(null); 33 | } 34 | } 35 | 36 | #if TINYIOC_INTERNAL 37 | internal 38 | #else 39 | public 40 | #endif 41 | static class TinyIoCAspNetExtensions 42 | { 43 | public static TinyIoC.TinyIoCContainer.RegisterOptions AsPerRequestSingleton(this TinyIoC.TinyIoCContainer.RegisterOptions registerOptions) 44 | { 45 | return TinyIoCContainer.RegisterOptions.ToCustomLifetimeManager(registerOptions, new HttpContextLifetimeProvider(), "per request singleton"); 46 | } 47 | 48 | public static TinyIoCContainer.MultiRegisterOptions AsPerRequestSingleton(this TinyIoCContainer.MultiRegisterOptions registerOptions) 49 | { 50 | return TinyIoCContainer.MultiRegisterOptions.ToCustomLifetimeManager(registerOptions, new HttpContextLifetimeProvider(), "per request singleton"); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/TinyIoC/TinyIoC.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netstandard1.2;netstandard1.3;netstandard1.4;netstandard1.5;netstandard1.6;netstandard2.0; 4 | 5 | 6 | netstandard1.2;netstandard1.3;netstandard1.4;netstandard1.5;netstandard1.6;netstandard2.0;portable46-net451+win81+wpa81;net45 7 | 8 | 9 | 10 | $(DefineConstants);NETSTANDARD;NETSTANDARD1_2 11 | 12 | 13 | 14 | $(DefineConstants);NETSTANDARD;NETSTANDARD1_3 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | $(DefineConstants);NETSTANDARD;NETSTANDARD1_4 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | $(DefineConstants);NETSTANDARD;NETSTANDARD1_5 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | $(DefineConstants);NETSTANDARD;NETSTANDARD1_6 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | $(DefineConstants);NETSTANDARD;NETSTANDARD2_0 47 | 48 | 49 | 50 | .NETPortable 51 | v4.6 52 | Profile151 53 | $(DefineConstants);PORTABLE 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 3.5 82 | 83 | 84 | 85 | 3.5 86 | 87 | 88 | 3.5 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | true 97 | true 98 | contentFiles/cs/any 99 | 100 | 101 | true 102 | true 103 | content 104 | 105 | 106 | -------------------------------------------------------------------------------- /src/TinyMessenger/TinyMessenger.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netstandard2.0 4 | 5 | 6 | netstandard2.0;net45 7 | 8 | 9 | 10 | $(DefineConstants);NETSTANDARD;NETSTANDARD2_0 11 | 12 | 13 | 14 | A simple messenger/event aggregator 15 | messaging,pubsub,aggregator 16 | 17 | 18 | 19 | 20 | 21 | 3.5 22 | 23 | 24 | 25 | 3.5 26 | 27 | 28 | 3.5 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | true 37 | true 38 | contentFiles/cs/any 39 | 40 | 41 | true 42 | true 43 | content 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /tests/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | 5 | -------------------------------------------------------------------------------- /tests/TinyIoC.Tests.ExternalTypes/ExternalTestClasses.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TinyIoC.Tests.ExternalTypes 7 | { 8 | public interface IExternalTestInterface 9 | { 10 | } 11 | 12 | public class ExternalTestClass : IExternalTestInterface 13 | { 14 | } 15 | 16 | public interface IExternalTestInterface2 17 | { 18 | } 19 | 20 | class ExternalTestClassInternal : IExternalTestInterface2 21 | { 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/TinyIoC.Tests.ExternalTypes/TinyIoC.Tests.ExternalTypes.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netstandard1.1 4 | 5 | 6 | netstandard1.1;net45 7 | 8 | 9 | 10 | $(DefineConstants);NETSTANDARD;NETSTANDARD1_1 11 | 12 | 13 | 14 | false 15 | Library 16 | 17 | 18 | 19 | 20 | 21 | 3.5 22 | 23 | 24 | 3.5 25 | 26 | 27 | 3.5 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /tests/TinyIoC.Tests/Fakes/FakeLifetimeProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TinyIoC.Tests.Fakes 7 | { 8 | public class FakeLifetimeProvider : TinyIoC.TinyIoCContainer.ITinyIoCObjectLifetimeProvider 9 | { 10 | public object TheObject { get; set; } 11 | 12 | public object GetObject() 13 | { 14 | return TheObject; 15 | } 16 | 17 | public void SetObject(object value) 18 | { 19 | TheObject = value; 20 | } 21 | 22 | public void ReleaseObject() 23 | { 24 | TheObject = null; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/TinyIoC.Tests/Helpers/AssertHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Reflection; 7 | 8 | namespace TinyIoC.Tests 9 | { 10 | internal class AssertHelper 11 | { 12 | internal static T ThrowsException(Action callback) 13 | where T : Exception 14 | { 15 | try 16 | { 17 | callback(); 18 | throw new InvalidOperationException("No exception was thrown."); 19 | } 20 | catch (Exception ex) 21 | { 22 | if (typeof(T).IsAssignableFrom(ex.GetType())) 23 | return (T)ex; 24 | else 25 | throw new InvalidOperationException(string.Format("Exception of type '{0}' expected, but got exception of type '{1}'.", 26 | typeof(T), ex.GetType()), ex); 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/TinyIoC.Tests/Helpers/ExceptionHelper.cs: -------------------------------------------------------------------------------- 1 | namespace TinyIoC.Tests.Helpers 2 | { 3 | using System; 4 | 5 | public static class ExceptionHelper 6 | { 7 | public static Exception Record(Action action) 8 | { 9 | try 10 | { 11 | action.Invoke(); 12 | 13 | return null; 14 | } 15 | catch (Exception e) 16 | { 17 | return e; 18 | } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /tests/TinyIoC.Tests/PlatformTestSuite/PlatformTests.cs: -------------------------------------------------------------------------------- 1 | #region Preprocessor Directives 2 | // Uncomment this line if you want the container to automatically 3 | // register the TinyMessenger messenger/event aggregator 4 | //#define TINYMESSENGER 5 | 6 | // Uncomment this line if you want to internalize this library 7 | //#define TINYIOC_INTERNAL 8 | 9 | // Uncomment this line if you want to target PCL. 10 | //#define PORTABLE 11 | 12 | // Preprocessor directives for enabling/disabling functionality 13 | // depending on platform features. If the platform has an appropriate 14 | // #DEFINE then these should be set automatically below. 15 | #define EXPRESSIONS // Platform supports System.Linq.Expressions 16 | #define COMPILED_EXPRESSIONS // Platform supports compiling expressions 17 | #define APPDOMAIN_GETASSEMBLIES // Platform supports getting all assemblies from the AppDomain object 18 | #define UNBOUND_GENERICS_GETCONSTRUCTORS // Platform supports GetConstructors on unbound generic types 19 | #define GETPARAMETERS_OPEN_GENERICS // Platform supports GetParameters on open generics 20 | #define RESOLVE_OPEN_GENERICS // Platform supports resolving open generics 21 | #define READER_WRITER_LOCK_SLIM // Platform supports ReaderWriterLockSlim 22 | 23 | #if PORTABLE 24 | #undef APPDOMAIN_GETASSEMBLIES 25 | #undef COMPILED_EXPRESSIONS 26 | #undef READER_WRITER_LOCK_SLIM 27 | #endif 28 | 29 | // CompactFramework / Windows Phone 7 30 | // By default does not support System.Linq.Expressions. 31 | // AppDomain object does not support enumerating all assemblies in the app domain. 32 | #if PocketPC || WINDOWS_PHONE 33 | #undef EXPRESSIONS 34 | #undef COMPILED_EXPRESSIONS 35 | #undef APPDOMAIN_GETASSEMBLIES 36 | #undef UNBOUND_GENERICS_GETCONSTRUCTORS 37 | #endif 38 | 39 | // PocketPC has a bizarre limitation on enumerating parameters on unbound generic methods. 40 | // We need to use a slower workaround in that case. 41 | #if PocketPC 42 | #undef GETPARAMETERS_OPEN_GENERICS 43 | #undef RESOLVE_OPEN_GENERICS 44 | #undef READER_WRITER_LOCK_SLIM 45 | #endif 46 | 47 | #if SILVERLIGHT 48 | #undef APPDOMAIN_GETASSEMBLIES 49 | #endif 50 | 51 | #if NETFX_CORE 52 | #undef APPDOMAIN_GETASSEMBLIES 53 | #undef RESOLVE_OPEN_GENERICS 54 | #endif 55 | 56 | #if COMPILED_EXPRESSIONS 57 | #define USE_OBJECT_CONSTRUCTOR 58 | #endif 59 | 60 | #endregion 61 | 62 | using System; 63 | using System.Collections.Generic; 64 | using System.Linq; 65 | using System.Text; 66 | using System.Reflection; 67 | 68 | namespace TinyIoC.Tests.PlatformTestSuite 69 | { 70 | public interface ILogger 71 | { 72 | void WriteLine(string text); 73 | } 74 | 75 | public class StringLogger : ILogger 76 | { 77 | private readonly StringBuilder builder = new StringBuilder(); 78 | 79 | public string Log 80 | { 81 | get { return builder.ToString(); } 82 | } 83 | 84 | 85 | public void WriteLine(string text) 86 | { 87 | builder.AppendLine(text); 88 | } 89 | } 90 | 91 | public class PlatformTests 92 | { 93 | #region TestClasses 94 | public class TestClassNoInterface 95 | { 96 | } 97 | 98 | public interface ITestInterface 99 | { 100 | } 101 | 102 | public interface ITestInterface2 103 | { 104 | } 105 | 106 | public class TestClassWithInterface : ITestInterface 107 | { 108 | } 109 | 110 | public class TestClassWithInterface2 : ITestInterface 111 | { 112 | } 113 | 114 | public class TestClassWithConcreteDependency 115 | { 116 | public TestClassNoInterface Dependency { get; set; } 117 | 118 | public TestClassWithConcreteDependency(TestClassNoInterface dependency) 119 | { 120 | Dependency = dependency; 121 | } 122 | 123 | public TestClassWithConcreteDependency() 124 | { 125 | 126 | } 127 | } 128 | 129 | public class TestClassWithInterfaceDependency 130 | { 131 | public ITestInterface Dependency { get; set; } 132 | 133 | public TestClassWithInterfaceDependency(ITestInterface dependency) 134 | { 135 | Dependency = dependency; 136 | } 137 | } 138 | 139 | public class TestClassWithParameters 140 | { 141 | public string StringProperty { get; set; } 142 | public int IntProperty { get; set; } 143 | 144 | public TestClassWithParameters(string stringProperty, int intProperty) 145 | { 146 | StringProperty = stringProperty; 147 | IntProperty = intProperty; 148 | } 149 | } 150 | 151 | public class GenericClass 152 | { 153 | 154 | } 155 | 156 | public class TestClassWithLazyFactory 157 | { 158 | private Func _Factory; 159 | public TestClassNoInterface Prop1 { get; private set; } 160 | public TestClassNoInterface Prop2 { get; private set; } 161 | 162 | /// 163 | /// Initializes a new instance of the TestClassWithLazyFactory class. 164 | /// 165 | /// 166 | public TestClassWithLazyFactory(Func factory) 167 | { 168 | _Factory = factory; 169 | Prop1 = _Factory.Invoke(); 170 | Prop2 = _Factory.Invoke(); 171 | } 172 | } 173 | 174 | public class TestClassWithNamedLazyFactory 175 | { 176 | private Func _Factory; 177 | public TestClassNoInterface Prop1 { get; private set; } 178 | public TestClassNoInterface Prop2 { get; private set; } 179 | 180 | /// 181 | /// Initializes a new instance of the TestClassWithLazyFactory class. 182 | /// 183 | /// 184 | public TestClassWithNamedLazyFactory(Func factory) 185 | { 186 | _Factory = factory; 187 | Prop1 = _Factory.Invoke("Testing"); 188 | Prop2 = _Factory.Invoke("Testing"); 189 | } 190 | } 191 | 192 | internal class TestclassWithNameAndParamsLazyFactory 193 | { 194 | private Func, TestClassWithParameters> _Factory; 195 | public TestClassWithParameters Prop1 { get; private set; } 196 | 197 | public TestclassWithNameAndParamsLazyFactory(Func, TestClassWithParameters> factory) 198 | { 199 | _Factory = factory; 200 | Prop1 = _Factory.Invoke("Testing", new Dictionary { { "stringProperty", "Testing" }, { "intProperty", 22 } }); 201 | } 202 | } 203 | 204 | internal class TestClassEnumerableDependency 205 | { 206 | IEnumerable _Enumerable; 207 | 208 | public int EnumerableCount { get { return _Enumerable == null ? 0 : _Enumerable.Count(); } } 209 | 210 | public TestClassEnumerableDependency(IEnumerable enumerable) 211 | { 212 | _Enumerable = enumerable; 213 | } 214 | } 215 | 216 | public interface IThing where T : new() 217 | { 218 | T Get(); 219 | } 220 | 221 | public class DefaultThing : IThing where T : new() 222 | { 223 | public T Get() 224 | { 225 | return new T(); 226 | } 227 | } 228 | #endregion 229 | 230 | 231 | private ILogger _Logger; 232 | private int _TestsRun; 233 | private int _TestsPassed; 234 | private int _TestsFailed; 235 | 236 | private List> _Tests; 237 | 238 | public PlatformTests(ILogger logger) 239 | { 240 | _Logger = logger; 241 | 242 | _Tests = new List>() 243 | { 244 | #if APPDOMAIN_GETASSEMBLIES 245 | AutoRegisterAppDomain, 246 | #endif 247 | AutoRegisterAssemblySpecified, 248 | AutoRegisterPredicateExclusion, 249 | RegisterConcrete, 250 | ResolveConcreteUnregisteredDefaultOptions, 251 | ResolveConcreteRegisteredDefaultOptions, 252 | RegisterNamedConcrete, 253 | ResolveNamedConcrete, 254 | RegisterInstance, 255 | RegisterInterface, 256 | RegisterStrongRef, 257 | RegisterWeakRef, 258 | RegisterFactory, 259 | #if EXPRESSIONS 260 | RegisterAndSpecifyConstructor, 261 | #endif 262 | RegisterBoundGeneric, 263 | #if EXPRESSIONS 264 | ResolveLazyFactory, 265 | ResolveNamedLazyFactory, 266 | ResolveNamedAndParamsLazyFactory, 267 | #endif 268 | ResolveAll, 269 | IEnumerableDependency, 270 | RegisterMultiple, 271 | NonGenericRegister, 272 | #if RESOLVE_OPEN_GENERICS 273 | OpenGenericRegistration, 274 | OpenGenericResolution, 275 | OpenGenericCanResolve 276 | #endif 277 | }; 278 | } 279 | 280 | public void RunTests(out int testsRun, out int testsPassed, out int testsFailed) 281 | { 282 | _TestsRun = 0; 283 | _TestsPassed = 0; 284 | _TestsFailed = 0; 285 | 286 | foreach (var test in _Tests) 287 | { 288 | var container = GetContainer(); 289 | try 290 | { 291 | _TestsRun++; 292 | if (test.Invoke(container, _Logger)) 293 | _TestsPassed++; 294 | else 295 | { 296 | _TestsFailed++; 297 | _Logger.WriteLine("Test Failed"); 298 | } 299 | } 300 | catch (Exception ex) 301 | { 302 | _TestsFailed++; 303 | _Logger.WriteLine(String.Format("Test Failed: {0}", ex.Message)); 304 | } 305 | } 306 | 307 | testsRun = _TestsRun; 308 | testsPassed = _TestsPassed; 309 | testsFailed = _TestsFailed; 310 | } 311 | 312 | private TinyIoC.TinyIoCContainer GetContainer() 313 | { 314 | return new TinyIoCContainer(); 315 | } 316 | 317 | private bool AutoRegisterAppDomain(TinyIoCContainer container, ILogger logger) 318 | { 319 | logger.WriteLine("AutoRegisterAppDomain"); 320 | container.AutoRegister(); 321 | container.Resolve(); 322 | return true; 323 | } 324 | 325 | private bool AutoRegisterAssemblySpecified(TinyIoCContainer container, ILogger logger) 326 | { 327 | logger.WriteLine("AutoRegisterAssemblySpecified"); 328 | container.AutoRegister(new[] { this.GetType().Assembly }); 329 | container.Resolve(); 330 | return true; 331 | } 332 | 333 | private bool RegisterConcrete(TinyIoCContainer container, ILogger logger) 334 | { 335 | logger.WriteLine("RegisterConcrete"); 336 | container.Register(); 337 | container.Resolve(); 338 | return true; 339 | } 340 | 341 | private bool ResolveConcreteUnregisteredDefaultOptions(TinyIoCContainer container, ILogger logger) 342 | { 343 | logger.WriteLine("ResolveConcreteUnregisteredDefaultOptions"); 344 | var output = container.Resolve(); 345 | 346 | return output is TestClassNoInterface; 347 | } 348 | 349 | private bool ResolveConcreteRegisteredDefaultOptions(TinyIoCContainer container, ILogger logger) 350 | { 351 | logger.WriteLine("ResolveConcreteRegisteredDefaultOptions"); 352 | container.Register(); 353 | var output = container.Resolve(); 354 | 355 | return output is TestClassNoInterface; 356 | } 357 | 358 | private bool RegisterNamedConcrete(TinyIoCContainer container, ILogger logger) 359 | { 360 | logger.WriteLine("RegisterNamedConcrete"); 361 | container.Register("Testing"); 362 | var output = container.Resolve("Testing"); 363 | 364 | return output is TestClassNoInterface; 365 | } 366 | 367 | private bool ResolveNamedConcrete(TinyIoCContainer container, ILogger logger) 368 | { 369 | logger.WriteLine("ResolveNamedConcrete"); 370 | container.Register("Testing"); 371 | var output = container.Resolve("Testing"); 372 | 373 | return output is TestClassNoInterface; 374 | } 375 | 376 | private bool RegisterInstance(TinyIoCContainer container, ILogger logger) 377 | { 378 | logger.WriteLine("RegisterInstance"); 379 | var obj = new TestClassNoInterface(); 380 | container.Register(obj); 381 | var output = container.Resolve(); 382 | return object.ReferenceEquals(obj, output); 383 | } 384 | 385 | private bool RegisterInterface(TinyIoCContainer container, ILogger logger) 386 | { 387 | logger.WriteLine("RegisterInterface"); 388 | container.Register(); 389 | var output = container.Resolve(); 390 | return output is ITestInterface; 391 | } 392 | 393 | private bool RegisterStrongRef(TinyIoCContainer container, ILogger logger) 394 | { 395 | logger.WriteLine("RegisterStrongRef"); 396 | var obj = new TestClassNoInterface(); 397 | container.Register(obj).WithStrongReference(); 398 | var output = container.Resolve(); 399 | 400 | return output is TestClassNoInterface; 401 | } 402 | 403 | private bool RegisterWeakRef(TinyIoCContainer container, ILogger logger) 404 | { 405 | logger.WriteLine("RegisterWeakRef"); 406 | var obj = new TestClassNoInterface(); 407 | container.Register(obj).WithWeakReference(); 408 | var output = container.Resolve(); 409 | 410 | return output is TestClassNoInterface; 411 | } 412 | 413 | private bool RegisterFactory(TinyIoCContainer container, ILogger logger) 414 | { 415 | logger.WriteLine("RegisterFactory"); 416 | container.Register((c, p) => new TestClassNoInterface()); 417 | var output = container.Resolve(); 418 | 419 | return output is TestClassNoInterface; 420 | } 421 | 422 | #if EXPRESSIONS 423 | private bool RegisterAndSpecifyConstructor(TinyIoCContainer container, ILogger logger) 424 | { 425 | logger.WriteLine("RegisterAndSpecifyConstructor"); 426 | container.Register().UsingConstructor(() => new TestClassWithConcreteDependency()); 427 | var output = container.Resolve(); 428 | 429 | return output is TestClassWithConcreteDependency; 430 | } 431 | #endif 432 | 433 | private bool RegisterBoundGeneric(TinyIoCContainer container, ILogger logger) 434 | { 435 | logger.WriteLine("RegisterBoundGeneric"); 436 | container.Register>(); 437 | var output = container.Resolve>(); 438 | 439 | return output is GenericClass; 440 | } 441 | 442 | #if EXPRESSIONS 443 | private bool ResolveLazyFactory(TinyIoCContainer container, ILogger logger) 444 | { 445 | logger.WriteLine("ResolveLazyFactory"); 446 | container.Register(); 447 | container.Register(); 448 | var output = container.Resolve(); 449 | return (output.Prop1 != null) && (output.Prop2 != null); 450 | } 451 | 452 | private bool ResolveNamedLazyFactory(TinyIoCContainer container, ILogger logger) 453 | { 454 | logger.WriteLine("ResolveNamedLazyFactory"); 455 | container.Register("Testing"); 456 | container.Register(); 457 | var output = container.Resolve(); 458 | return (output.Prop1 != null) && (output.Prop2 != null); 459 | } 460 | 461 | private bool ResolveNamedAndParamsLazyFactory(TinyIoCContainer container, ILogger logger) 462 | { 463 | logger.WriteLine("ResolveNamedAndParamsLazyFactory"); 464 | container.Register("Testing"); 465 | container.Register(); 466 | var output = container.Resolve(); 467 | return (output.Prop1 != null); 468 | } 469 | 470 | #endif 471 | 472 | private bool ResolveAll(TinyIoCContainer container, ILogger logger) 473 | { 474 | logger.WriteLine("ResolveAll"); 475 | container.Register(); 476 | container.Register("Named1"); 477 | container.Register("Named2"); 478 | 479 | IEnumerable result = container.ResolveAll(); 480 | 481 | return (result.Count() == 3); 482 | } 483 | 484 | private bool IEnumerableDependency(TinyIoCContainer container, ILogger logger) 485 | { 486 | logger.WriteLine("IEnumerableDependency"); 487 | container.Register(); 488 | container.Register("Named1"); 489 | container.Register("Named2"); 490 | container.Register(); 491 | 492 | var result = container.Resolve(); 493 | 494 | return (result.EnumerableCount == 2); 495 | } 496 | 497 | private bool RegisterMultiple(TinyIoCContainer container, ILogger logger) 498 | { 499 | logger.WriteLine("RegisterMultiple"); 500 | container.RegisterMultiple(new Type[] { typeof(TestClassWithInterface), typeof(TestClassWithInterface2) }); 501 | 502 | var result = container.ResolveAll(); 503 | 504 | return (result.Count() == 2); 505 | } 506 | 507 | private bool NonGenericRegister(TinyIoCContainer container, ILogger logger) 508 | { 509 | logger.WriteLine("NonGenericRegister"); 510 | container.Register(typeof(ITestInterface), typeof(TestClassWithInterface)); 511 | 512 | var result = container.Resolve(ResolveOptions.FailUnregisteredAndNameNotFound); 513 | 514 | return true; 515 | } 516 | 517 | private bool AutoRegisterPredicateExclusion(TinyIoCContainer container, ILogger logger) 518 | { 519 | logger.WriteLine("AutoRegisterPredicateExclusion"); 520 | container.AutoRegister(t => t != typeof(ITestInterface)); 521 | 522 | try 523 | { 524 | container.Resolve(); 525 | return false; 526 | } 527 | catch (TinyIoCResolutionException) 528 | { 529 | } 530 | 531 | return true; 532 | } 533 | 534 | private bool OpenGenericRegistration(TinyIoCContainer container, ILogger logger) 535 | { 536 | logger.WriteLine("OpenGenericRegistration"); 537 | 538 | container.Register(typeof(IThing<>), typeof(DefaultThing<>)); 539 | 540 | return true; 541 | } 542 | 543 | private bool OpenGenericResolution(TinyIoCContainer container, ILogger logger) 544 | { 545 | logger.WriteLine("OpenGenericResolution"); 546 | 547 | container.Register(typeof(IThing<>), typeof(DefaultThing<>)); 548 | 549 | var result = container.Resolve>(); 550 | 551 | return result != null && result.GetType() == typeof(DefaultThing); 552 | } 553 | 554 | private bool OpenGenericCanResolve(TinyIoCContainer container, ILogger logger) 555 | { 556 | logger.WriteLine("OpenGenericCanResolve"); 557 | 558 | container.Register(typeof(IThing<>), typeof(DefaultThing<>)); 559 | 560 | return container.CanResolve(typeof(IThing)); 561 | } 562 | } 563 | } 564 | -------------------------------------------------------------------------------- /tests/TinyIoC.Tests/TestData/BasicClasses.cs: -------------------------------------------------------------------------------- 1 | //=============================================================================== 2 | // TinyIoC 3 | // 4 | // An easy to use, hassle free, Inversion of Control Container for small projects 5 | // and beginners alike. 6 | // 7 | // http://hg.grumpydev.com/tinyioc 8 | //=============================================================================== 9 | // Copyright © Steven Robbins. All rights reserved. 10 | // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY 11 | // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT 12 | // LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 13 | // FITNESS FOR A PARTICULAR PURPOSE. 14 | //=============================================================================== 15 | 16 | using System; 17 | using System.Collections.Generic; 18 | using System.Linq; 19 | using System.Text; 20 | 21 | namespace TinyIoC.Tests.TestData 22 | { 23 | namespace BasicClasses 24 | { 25 | internal interface ITestInterface 26 | { 27 | } 28 | 29 | internal interface ITestInterface 30 | { 31 | } 32 | 33 | internal class TestClassDefaultCtor : ITestInterface 34 | { 35 | public string Prop1 { get; set; } 36 | 37 | public TestClassDefaultCtor() 38 | { 39 | 40 | } 41 | 42 | public static ITestInterface CreateNew(TinyIoCContainer container) 43 | { 44 | return new TestClassDefaultCtor() { Prop1 = "Testing" }; 45 | } 46 | } 47 | 48 | internal interface ITestInterface2 49 | { 50 | } 51 | 52 | internal class TestClass2 : ITestInterface2 53 | { 54 | } 55 | 56 | internal class TestClassWithContainerDependency 57 | { 58 | public TinyIoCContainer _Container { get; private set; } 59 | 60 | public TestClassWithContainerDependency(TinyIoCContainer container) 61 | { 62 | if (container == null) 63 | throw new ArgumentNullException("container"); 64 | 65 | _Container = container; 66 | } 67 | } 68 | 69 | internal class TestClassWithInterfaceDependency : ITestInterface2 70 | { 71 | public ITestInterface Dependency { get; set; } 72 | 73 | public int Param1 { get; private set; } 74 | 75 | public string Param2 { get; private set; } 76 | 77 | public TestClassWithInterfaceDependency(ITestInterface dependency) 78 | { 79 | if (dependency == null) 80 | throw new ArgumentNullException("dependency"); 81 | 82 | Dependency = dependency; 83 | } 84 | 85 | public TestClassWithInterfaceDependency(ITestInterface dependency, int param1, string param2) 86 | { 87 | Dependency = dependency; 88 | Param1 = param1; 89 | Param2 = param2; 90 | } 91 | } 92 | 93 | internal class TestClassWithDependency 94 | { 95 | TestClassDefaultCtor Dependency { get; set; } 96 | 97 | public int Param1 { get; private set; } 98 | 99 | public string Param2 { get; private set; } 100 | 101 | public TestClassWithDependency(TestClassDefaultCtor dependency) 102 | { 103 | if (dependency == null) 104 | throw new ArgumentNullException("dependency"); 105 | 106 | Dependency = dependency; 107 | } 108 | 109 | public TestClassWithDependency(TestClassDefaultCtor dependency, int param1, string param2) 110 | { 111 | Param1 = param1; 112 | Param2 = param2; 113 | } 114 | } 115 | 116 | internal class TestClassPrivateCtor 117 | { 118 | private TestClassPrivateCtor() 119 | { 120 | } 121 | } 122 | 123 | internal class TestClassProtectedCtor 124 | { 125 | protected TestClassProtectedCtor() 126 | { 127 | } 128 | } 129 | 130 | internal class TestSubclassProtectedCtor 131 | { 132 | public TestSubclassProtectedCtor() 133 | { 134 | } 135 | } 136 | 137 | internal class TestClassWithParameters 138 | { 139 | public string StringProperty { get; set; } 140 | public int IntProperty { get; set; } 141 | 142 | public TestClassWithParameters(string stringProperty, int intProperty) 143 | { 144 | StringProperty = stringProperty; 145 | IntProperty = intProperty; 146 | } 147 | } 148 | 149 | internal class TestClassWithDependencyAndParameters 150 | { 151 | TestClassDefaultCtor Dependency { get; set; } 152 | 153 | public int Param1 { get; private set; } 154 | 155 | public string Param2 { get; private set; } 156 | 157 | public TestClassWithDependencyAndParameters(TestClassDefaultCtor dependency, int param1, string param2) 158 | { 159 | if (dependency == null) 160 | throw new ArgumentNullException("dependency"); 161 | 162 | Dependency = dependency; 163 | Param1 = param1; 164 | Param2 = param2; 165 | } 166 | } 167 | 168 | internal class TestClassNoInterfaceDefaultCtor 169 | { 170 | public TestClassNoInterfaceDefaultCtor() 171 | { 172 | 173 | } 174 | } 175 | 176 | internal class TestClassNoInterfaceDependency 177 | { 178 | public ITestInterface Dependency { get; set; } 179 | 180 | public TestClassNoInterfaceDependency(ITestInterface dependency) 181 | { 182 | if (dependency == null) 183 | throw new ArgumentNullException("dependency"); 184 | 185 | Dependency = dependency; 186 | } 187 | } 188 | 189 | public class DisposableTestClassWithInterface : IDisposable, ITestInterface 190 | { 191 | public void Dispose() 192 | { 193 | 194 | } 195 | } 196 | 197 | public class GenericClassWithInterface : ITestInterface 198 | { 199 | public I Prop1 { get; set; } 200 | public S Prop2 { get; set; } 201 | 202 | public GenericClassWithInterface() 203 | { 204 | 205 | } 206 | 207 | public GenericClassWithInterface(I prop1, S prop2) 208 | { 209 | Prop1 = prop1; 210 | Prop2 = prop2; 211 | } 212 | } 213 | 214 | internal class GenericClassWithGenericInterface : ITestInterface 215 | { 216 | public I Prop1 { get; set; } 217 | public S Prop2 { get; set; } 218 | 219 | public GenericClassWithGenericInterface() 220 | { 221 | } 222 | 223 | public GenericClassWithGenericInterface(I prop1, S prop2) 224 | { 225 | Prop1 = prop1; 226 | Prop2 = prop2; 227 | } 228 | } 229 | 230 | internal class GenericClassWithParametersAndDependencies 231 | { 232 | public ITestInterface2 Dependency { get; private set; } 233 | public I Prop1 { get; set; } 234 | public S Prop2 { get; set; } 235 | 236 | public GenericClassWithParametersAndDependencies(ITestInterface2 dependency) 237 | { 238 | Dependency = dependency; 239 | } 240 | 241 | public GenericClassWithParametersAndDependencies(ITestInterface2 dependency, I prop1, S prop2) 242 | { 243 | Dependency = dependency; 244 | Prop1 = prop1; 245 | Prop2 = prop2; 246 | } 247 | } 248 | 249 | internal class TestClassWithLazyFactory 250 | { 251 | private Func _Factory; 252 | public TestClassDefaultCtor Prop1 { get; private set; } 253 | public TestClassDefaultCtor Prop2 { get; private set; } 254 | 255 | /// 256 | /// Initializes a new instance of the TestClassWithLazyFactory class. 257 | /// 258 | /// 259 | public TestClassWithLazyFactory(Func factory) 260 | { 261 | _Factory = factory; 262 | } 263 | 264 | public void Method1() 265 | { 266 | Prop1 = _Factory.Invoke(); 267 | } 268 | 269 | public void Method2() 270 | { 271 | Prop2 = _Factory.Invoke(); 272 | } 273 | 274 | } 275 | 276 | internal class TestClassWithNamedLazyFactory 277 | { 278 | private Func _Factory; 279 | public TestClassDefaultCtor Prop1 { get; private set; } 280 | public TestClassDefaultCtor Prop2 { get; private set; } 281 | 282 | /// 283 | /// Initializes a new instance of the TestClassWithLazyFactory class. 284 | /// 285 | /// 286 | public TestClassWithNamedLazyFactory(Func factory) 287 | { 288 | _Factory = factory; 289 | } 290 | 291 | public void Method1() 292 | { 293 | Prop1 = _Factory.Invoke("Testing"); 294 | } 295 | 296 | public void Method2() 297 | { 298 | Prop2 = _Factory.Invoke(String.Empty); 299 | } 300 | 301 | } 302 | 303 | internal class TestclassWithNameAndParamsLazyFactory 304 | { 305 | private Func, TestClassWithParameters> _Factory; 306 | public TestClassWithParameters Prop1 { get; private set; } 307 | 308 | /// 309 | /// Initializes a new instance of the TestclassWithNameAndParamsLazyFactory class. 310 | /// 311 | /// 312 | public TestclassWithNameAndParamsLazyFactory(Func, TestClassWithParameters> factory) 313 | { 314 | _Factory = factory; 315 | Prop1 = _Factory.Invoke("", new Dictionary { { "stringProperty", "Testing" }, { "intProperty", 22 } }); 316 | } 317 | 318 | } 319 | 320 | internal class TestClassMultiDepsMultiCtors 321 | { 322 | public TestClassDefaultCtor Prop1 { get; private set; } 323 | public TestClassDefaultCtor Prop2 { get; private set; } 324 | public int NumberOfDepsResolved { get; private set; } 325 | 326 | public TestClassMultiDepsMultiCtors(TestClassDefaultCtor prop1) 327 | { 328 | Prop1 = prop1; 329 | NumberOfDepsResolved = 1; 330 | } 331 | 332 | public TestClassMultiDepsMultiCtors(TestClassDefaultCtor prop1, TestClassDefaultCtor prop2) 333 | { 334 | Prop1 = prop1; 335 | Prop2 = prop2; 336 | NumberOfDepsResolved = 2; 337 | } 338 | } 339 | 340 | internal class TestClassConstructorFailure 341 | { 342 | /// 343 | /// Initializes a new instance of the TestClassConstructorFailure class. 344 | /// 345 | public TestClassConstructorFailure() 346 | { 347 | throw new NotImplementedException(); 348 | } 349 | } 350 | 351 | internal abstract class TestClassBase 352 | { 353 | } 354 | 355 | internal class TestClassWithBaseClass : TestClassBase 356 | { 357 | 358 | } 359 | 360 | internal class TestClassPropertyDependencies 361 | { 362 | public ITestInterface Property1 { get; set; } 363 | public ITestInterface2 Property2 { get; set; } 364 | public int Property3 { get; set; } 365 | public string Property4 { get; set; } 366 | 367 | public TestClassDefaultCtor ConcreteProperty { get; set; } 368 | 369 | public ITestInterface ReadOnlyProperty { get; private set; } 370 | public ITestInterface2 WriteOnlyProperty { internal get; set; } 371 | 372 | /// 373 | /// Initializes a new instance of the TestClassPropertyDependencies class. 374 | /// 375 | public TestClassPropertyDependencies() 376 | { 377 | 378 | } 379 | } 380 | 381 | internal class TestClassEnumerableDependency 382 | { 383 | public IEnumerable Enumerable {get; private set;} 384 | 385 | public int EnumerableCount { get { return Enumerable == null ? 0 : Enumerable.Count(); } } 386 | 387 | public TestClassEnumerableDependency(IEnumerable enumerable) 388 | { 389 | Enumerable = enumerable; 390 | } 391 | } 392 | 393 | internal class TestClassEnumerableDependency2 394 | { 395 | public IEnumerable Enumerable { get; private set; } 396 | 397 | public int EnumerableCount { get { return Enumerable == null ? 0 : Enumerable.Count(); } } 398 | 399 | public TestClassEnumerableDependency2(IEnumerable enumerable) 400 | { 401 | Enumerable = enumerable; 402 | } 403 | } 404 | 405 | public interface IThing where T: new() 406 | { 407 | T Get(); 408 | } 409 | 410 | public class DefaultThing : IThing where T : new() 411 | { 412 | public T Get() 413 | { 414 | return new T(); 415 | } 416 | } 417 | 418 | internal class TestClassWithConstructorAttrib 419 | { 420 | [TinyIoCConstructor] 421 | public TestClassWithConstructorAttrib() 422 | { 423 | AttributeConstructorUsed = true; 424 | } 425 | 426 | public TestClassWithConstructorAttrib(object someParameter) 427 | { 428 | AttributeConstructorUsed = false; 429 | } 430 | 431 | public bool AttributeConstructorUsed { get; private set; } 432 | } 433 | 434 | internal class TestClassWithInternalConstructorAttrib 435 | { 436 | [TinyIoCConstructor] 437 | internal TestClassWithInternalConstructorAttrib() 438 | { 439 | AttributeConstructorUsed = true; 440 | } 441 | 442 | public TestClassWithInternalConstructorAttrib(object someParameter) 443 | { 444 | AttributeConstructorUsed = false; 445 | } 446 | 447 | public bool AttributeConstructorUsed { get; private set; } 448 | } 449 | 450 | internal class TestClassWithManyConstructorAttribs 451 | { 452 | [TinyIoCConstructor] 453 | public TestClassWithManyConstructorAttribs() 454 | { 455 | MostGreedyAttribCtorUsed = false; 456 | } 457 | 458 | [TinyIoCConstructor] 459 | public TestClassWithManyConstructorAttribs(object someParameter) 460 | { 461 | MostGreedyAttribCtorUsed = true; 462 | } 463 | 464 | public TestClassWithManyConstructorAttribs(object a, object b) 465 | { 466 | MostGreedyAttribCtorUsed = false; 467 | } 468 | 469 | public bool MostGreedyAttribCtorUsed { get; private set; } 470 | } 471 | } 472 | } 473 | -------------------------------------------------------------------------------- /tests/TinyIoC.Tests/TestData/NestedClassDependencies.cs: -------------------------------------------------------------------------------- 1 | //=============================================================================== 2 | // TinyIoC 3 | // 4 | // An easy to use, hassle free, Inversion of Control Container for small projects 5 | // and beginners alike. 6 | // 7 | // http://hg.grumpydev.com/tinyioc 8 | //=============================================================================== 9 | // Copyright © Steven Robbins. All rights reserved. 10 | // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY 11 | // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT 12 | // LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 13 | // FITNESS FOR A PARTICULAR PURPOSE. 14 | //=============================================================================== 15 | 16 | using System; 17 | using System.Collections.Generic; 18 | using System.Linq; 19 | using System.Text; 20 | 21 | namespace TinyIoC.Tests.TestData 22 | { 23 | namespace NestedClassDependencies 24 | { 25 | internal class Service1 26 | { 27 | } 28 | 29 | internal class Service2 30 | { 31 | Service3 Service3; 32 | 33 | public Service2(Service3 service3) 34 | { 35 | if (service3 == null) 36 | throw new ArgumentNullException("service3"); 37 | 38 | this.Service3 = service3; 39 | } 40 | } 41 | 42 | internal class Service3 43 | { 44 | } 45 | 46 | internal class RootClass 47 | { 48 | Service1 service1; 49 | Service2 service2; 50 | 51 | public string StringProperty { get; set; } 52 | public int IntProperty { get; set; } 53 | 54 | public RootClass(Service1 service1, Service2 service2) 55 | : this(service1, service2, "DEFAULT", 1976) 56 | { 57 | } 58 | 59 | public RootClass(Service1 service1, Service2 service2, string stringProperty, int intProperty) 60 | { 61 | if (service1 == null) 62 | throw new ArgumentNullException("service1"); 63 | 64 | if (service2 == null) 65 | throw new ArgumentNullException("service2"); 66 | 67 | this.service1 = service1; 68 | this.service2 = service2; 69 | StringProperty = stringProperty; 70 | IntProperty = intProperty; 71 | } 72 | } 73 | } 74 | } 75 | 76 | -------------------------------------------------------------------------------- /tests/TinyIoC.Tests/TestData/NestedInterfaceDependencies.cs: -------------------------------------------------------------------------------- 1 | //=============================================================================== 2 | // TinyIoC 3 | // 4 | // An easy to use, hassle free, Inversion of Control Container for small projects 5 | // and beginners alike. 6 | // 7 | // http://hg.grumpydev.com/tinyioc 8 | //=============================================================================== 9 | // Copyright © Steven Robbins. All rights reserved. 10 | // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY 11 | // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT 12 | // LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 13 | // FITNESS FOR A PARTICULAR PURPOSE. 14 | //=============================================================================== 15 | 16 | using System; 17 | using System.Collections.Generic; 18 | using System.Linq; 19 | using System.Text; 20 | 21 | namespace TinyIoC.Tests.TestData 22 | { 23 | namespace NestedInterfaceDependencies 24 | { 25 | internal interface IService1 26 | { 27 | } 28 | 29 | internal interface IService2 30 | { 31 | IService3 Service3 { get; } 32 | } 33 | 34 | internal interface IService3 35 | { 36 | } 37 | 38 | internal interface IService4 39 | { 40 | IService2 Service2 { get; } 41 | } 42 | 43 | internal interface IService5 44 | { 45 | IService4 Service4 { get; } 46 | } 47 | 48 | internal class Service1 : IService1 49 | { 50 | } 51 | 52 | internal class Service2 : IService2 53 | { 54 | public IService3 Service3 { get; private set; } 55 | 56 | public Service2(IService3 service3) 57 | { 58 | this.Service3 = service3; 59 | } 60 | } 61 | 62 | internal class Service3 : IService3 63 | { 64 | } 65 | 66 | internal class Service4 : IService4 67 | { 68 | public IService2 Service2 { get; private set; } 69 | 70 | public Service4(IService2 service1) 71 | { 72 | Service2 = service1; 73 | } 74 | } 75 | 76 | internal class Service5 : IService5 77 | { 78 | public Service5(IService4 service4) 79 | { 80 | Service4 = service4; 81 | } 82 | 83 | public IService4 Service4 { get; private set; } 84 | } 85 | 86 | 87 | internal interface IRoot 88 | { 89 | 90 | } 91 | 92 | internal class RootClass : IRoot 93 | { 94 | IService1 service1; 95 | IService2 service2; 96 | 97 | public string StringProperty { get; set; } 98 | public int IntProperty { get; set; } 99 | 100 | public RootClass(IService1 service1, IService2 service2) : this(service1, service2, "DEFAULT", 1976) 101 | { 102 | } 103 | 104 | public RootClass(IService1 service1, IService2 service2, string stringProperty, int intProperty) 105 | { 106 | this.service1 = service1; 107 | this.service2 = service2; 108 | StringProperty = stringProperty; 109 | IntProperty = intProperty; 110 | } 111 | } 112 | } 113 | 114 | // Nested deps with func 115 | public interface IStateManager 116 | { 117 | bool MoveToState(string state, object data); 118 | void Init(); 119 | } 120 | 121 | public interface IView 122 | { 123 | object GetView(); 124 | } 125 | 126 | public interface IViewManager 127 | { 128 | bool LoadView(IView view); 129 | } 130 | 131 | public class MainView : IView, IViewManager 132 | { 133 | 134 | public IView LoadedView { get; private set; } 135 | 136 | public object GetView() 137 | { 138 | return this; 139 | } 140 | 141 | 142 | 143 | public bool LoadView(IView view) 144 | { 145 | if (view == null) 146 | throw new ArgumentNullException("view"); 147 | 148 | LoadedView = view; 149 | return true; 150 | } 151 | 152 | } 153 | 154 | public class ViewCollection 155 | { 156 | private readonly IEnumerable _views; 157 | 158 | public ViewCollection(IEnumerable views) 159 | { 160 | _views = views; 161 | } 162 | 163 | public IEnumerable Views 164 | { 165 | get { return _views; } 166 | } 167 | } 168 | 169 | public class SplashView : IView 170 | { 171 | public object GetView() 172 | { 173 | return this; 174 | } 175 | } 176 | 177 | public class StateManager : IStateManager 178 | { 179 | IViewManager _ViewManager; 180 | Func _ViewFactory; 181 | 182 | public bool MoveToState(string state, object data) 183 | { 184 | var view = _ViewFactory.Invoke(state); 185 | return _ViewManager.LoadView(view); 186 | } 187 | 188 | public void Init() 189 | { 190 | this.MoveToState("SplashView", null); 191 | } 192 | 193 | /// 194 | /// Initializes a new instance of the StateManager class. 195 | /// 196 | /// 197 | /// 198 | public StateManager(IViewManager viewManager, Func viewFactory) 199 | { 200 | _ViewManager = viewManager; 201 | _ViewFactory = viewFactory; 202 | } 203 | } 204 | 205 | 206 | 207 | } 208 | -------------------------------------------------------------------------------- /tests/TinyIoC.Tests/TestData/TinyMessengerTestData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using TinyMessenger; 6 | 7 | namespace TinyIoC.Tests.TestData 8 | { 9 | public class TestMessage : TinyMessageBase 10 | { 11 | public TestMessage(object sender) : base(sender) 12 | { 13 | 14 | } 15 | } 16 | 17 | public class TestProxy : ITinyMessageProxy 18 | { 19 | public ITinyMessage Message {get; private set;} 20 | 21 | public void Deliver(ITinyMessage message, ITinyMessageSubscription subscription) 22 | { 23 | this.Message = message; 24 | subscription.Deliver(message); 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /tests/TinyIoC.Tests/TestData/UtilityMethods.cs: -------------------------------------------------------------------------------- 1 | //=============================================================================== 2 | // TinyIoC 3 | // 4 | // An easy to use, hassle free, Inversion of Control Container for small projects 5 | // and beginners alike. 6 | // 7 | // http://hg.grumpydev.com/tinyioc 8 | //=============================================================================== 9 | // Copyright © Steven Robbins. All rights reserved. 10 | // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY 11 | // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT 12 | // LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 13 | // FITNESS FOR A PARTICULAR PURPOSE. 14 | //=============================================================================== 15 | 16 | using System; 17 | using System.Collections.Generic; 18 | using System.Linq; 19 | using System.Text; 20 | using TinyIoC.Tests.TestData.BasicClasses; 21 | using TinyMessenger; 22 | 23 | namespace TinyIoC.Tests.TestData 24 | { 25 | public class UtilityMethods 26 | { 27 | internal static TinyIoCContainer GetContainer() 28 | { 29 | return new TinyIoCContainer(); 30 | } 31 | 32 | internal static void RegisterInstanceStrongRef(TinyIoCContainer container) 33 | { 34 | var item = new TestClassDefaultCtor(); 35 | item.Prop1 = "Testing"; 36 | container.Register(item).WithStrongReference(); 37 | } 38 | 39 | internal static void RegisterInstanceWeakRef(TinyIoCContainer container) 40 | { 41 | var item = new TestClassDefaultCtor(); 42 | item.Prop1 = "Testing"; 43 | container.Register(item).WithWeakReference(); 44 | } 45 | 46 | internal static void RegisterFactoryStrongRef(TinyIoCContainer container) 47 | { 48 | var source = new TestClassDefaultCtor(); 49 | source.Prop1 = "Testing"; 50 | 51 | var item = new Func((c, p) => source); 52 | container.Register(item).WithStrongReference(); 53 | } 54 | 55 | internal static void RegisterFactoryWeakRef(TinyIoCContainer container) 56 | { 57 | var source = new TestClassDefaultCtor(); 58 | source.Prop1 = "Testing"; 59 | 60 | var item = new Func((c, p) => source); 61 | container.Register(item).WithWeakReference(); 62 | } 63 | 64 | public static ITinyMessengerHub GetMessenger() 65 | { 66 | return new TinyMessengerHub(); 67 | } 68 | 69 | public static void FakeDeliveryAction(T message) 70 | where T:ITinyMessage 71 | { 72 | } 73 | 74 | public static bool FakeMessageFilter(T message) 75 | where T:ITinyMessage 76 | { 77 | return true; 78 | } 79 | 80 | public static TinyMessageSubscriptionToken GetTokenWithOutOfScopeMessenger() 81 | { 82 | var messenger = UtilityMethods.GetMessenger(); 83 | 84 | var token = new TinyMessageSubscriptionToken(messenger, typeof(TestMessage)); 85 | 86 | return token; 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /tests/TinyIoC.Tests/TinyIoC.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netcoreapp3.1 4 | 5 | 6 | netcoreapp3.1;net45 7 | 8 | 9 | 10 | $(DefineConstants);NETSTANDARD;NETSTANDARD2_0 11 | 12 | 13 | 14 | false 15 | Library 16 | 17 | 18 | 19 | TRACE;MOQ;RESOLVE_OPEN_GENERICS 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 3.5 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /tests/TinyIoC.Tests/TinyIoCFunctionalTests.cs: -------------------------------------------------------------------------------- 1 | //=============================================================================== 2 | // TinyIoC 3 | // 4 | // An easy to use, hassle free, Inversion of Control Container for small projects 5 | // and beginners alike. 6 | // 7 | // http://hg.grumpydev.com/tinyioc 8 | //=============================================================================== 9 | // Copyright © Steven Robbins. All rights reserved. 10 | // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY 11 | // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT 12 | // LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 13 | // FITNESS FOR A PARTICULAR PURPOSE. 14 | //=============================================================================== 15 | 16 | using System; 17 | using System.Collections.Generic; 18 | using System.Linq; 19 | using System.Text; 20 | using System.Reflection; 21 | using TinyIoC.Tests.TestData; 22 | using TinyIoC.Tests.TestData.BasicClasses; 23 | using NestedInterfaceDependencies = TinyIoC.Tests.TestData.NestedInterfaceDependencies; 24 | using NestedClassDependencies = TinyIoC.Tests.TestData.NestedClassDependencies; 25 | 26 | #if !NETFX_CORE 27 | using Microsoft.VisualStudio.TestTools.UnitTesting; 28 | #else 29 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 30 | #endif 31 | 32 | namespace TinyIoC.Tests 33 | { 34 | using NestedInterfaceDependencies; 35 | 36 | using TinyIoC.Tests.PlatformTestSuite; 37 | 38 | [TestClass] 39 | public class TinyIoCFunctionalTests 40 | { 41 | [TestMethod] 42 | public void NestedInterfaceDependencies_CorrectlyRegistered_ResolvesRoot() 43 | { 44 | var container = UtilityMethods.GetContainer(); 45 | container.Register(); 46 | container.Register(); 47 | container.Register(); 48 | container.Register(); 49 | 50 | var result = container.Resolve(); 51 | 52 | Assert.IsInstanceOfType(result, typeof(NestedInterfaceDependencies.RootClass)); 53 | } 54 | 55 | [TestMethod] 56 | //[ExpectedException(typeof(TinyIoCResolutionException))] 57 | public void NestedInterfaceDependencies_MissingIService3Registration_ThrowsExceptionWithDefaultSettings() 58 | { 59 | var container = UtilityMethods.GetContainer(); 60 | container.Register(); 61 | container.Register(); 62 | container.Register(); 63 | 64 | AssertHelper.ThrowsException(() => container.Resolve()); 65 | 66 | //Assert.IsInstanceOfType(result, typeof(NestedInterfaceDependencies.RootClass)); 67 | } 68 | 69 | [TestMethod] 70 | public void NestedClassDependencies_CorrectlyRegistered_ResolvesRoot() 71 | { 72 | var container = UtilityMethods.GetContainer(); 73 | container.Register(); 74 | container.Register(); 75 | container.Register(); 76 | container.Register(); 77 | 78 | var result = container.Resolve(); 79 | 80 | Assert.IsInstanceOfType(result, typeof(NestedClassDependencies.RootClass)); 81 | } 82 | 83 | [TestMethod] 84 | public void NestedClassDependencies_UsingConstructorFromAnotherType_ThrowsException() 85 | { 86 | var container = UtilityMethods.GetContainer(); 87 | var registerOptions = container.Register(); 88 | 89 | AssertHelper.ThrowsException 90 | (() => registerOptions.UsingConstructor(() => new RootClass(null, null))); 91 | } 92 | 93 | [TestMethod] 94 | public void NestedClassDependencies_MissingService3Registration_ResolvesRootResolutionOn() 95 | { 96 | var container = UtilityMethods.GetContainer(); 97 | container.Register(); 98 | container.Register(); 99 | container.Register(); 100 | 101 | var result = container.Resolve(new ResolveOptions() { UnregisteredResolutionAction = UnregisteredResolutionActions.AttemptResolve }); 102 | 103 | Assert.IsInstanceOfType(result, typeof(NestedClassDependencies.RootClass)); 104 | } 105 | 106 | [TestMethod] 107 | //[ExpectedException(typeof(TinyIoCResolutionException))] 108 | public void NestedClassDependencies_MissingService3RegistrationAndUnRegisteredResolutionOff_ThrowsException() 109 | { 110 | var container = UtilityMethods.GetContainer(); 111 | container.Register(); 112 | container.Register(); 113 | container.Register(); 114 | 115 | AssertHelper.ThrowsException(() => container.Resolve(new ResolveOptions() { UnregisteredResolutionAction = UnregisteredResolutionActions.Fail })); 116 | 117 | //Assert.IsInstanceOfType(result, typeof(NestedClassDependencies.RootClass)); 118 | } 119 | 120 | [TestMethod] 121 | public void NestedInterfaceDependencies_JustAutoRegisterCalled_ResolvesRoot() 122 | { 123 | var container = UtilityMethods.GetContainer(); 124 | container.AutoRegister(new[] { this.GetType().Assembly }); 125 | 126 | var result = container.Resolve(); 127 | 128 | Assert.IsInstanceOfType(result, typeof(NestedInterfaceDependencies.RootClass)); 129 | } 130 | 131 | [TestMethod] 132 | public void Dependency_Hierarchy_With_Named_Factories_Resolves_All_Correctly() 133 | { 134 | var container = UtilityMethods.GetContainer(); 135 | var mainView = new MainView(); 136 | container.Register(mainView); 137 | container.Register(mainView, "MainView"); 138 | container.Register("SplashView").UsingConstructor(() => new SplashView()); 139 | container.Resolve("MainView"); 140 | container.Register(); 141 | var stateManager = container.Resolve(); 142 | 143 | stateManager.Init(); 144 | 145 | Assert.IsInstanceOfType(mainView.LoadedView, typeof(SplashView)); 146 | } 147 | 148 | [TestMethod] 149 | public void Dependency_Hierarchy_Resolves_IEnumerable_Correctly() 150 | { 151 | var container = UtilityMethods.GetContainer(); 152 | var mainView = new MainView(); 153 | container.Register(mainView, "MainView"); 154 | container.Register("SplashView").UsingConstructor(() => new SplashView()); 155 | var viewCollection = container.Resolve(); 156 | Assert.AreEqual(viewCollection.Views.Count(), 2); 157 | } 158 | 159 | [TestMethod] 160 | public void When_Unable_To_Resolve_Nested_Dependency_Should_Include_That_Type_In_The_Exception() 161 | { 162 | var container = UtilityMethods.GetContainer(); 163 | container.Register(); 164 | container.Register(); 165 | container.Register(); 166 | 167 | TinyIoCResolutionException e = null; 168 | try 169 | { 170 | container.Resolve(); 171 | } 172 | catch (TinyIoCResolutionException ex) 173 | { 174 | e = ex; 175 | } 176 | 177 | Assert.IsNotNull(e); 178 | Assert.IsTrue(e.ToString().Contains("NestedInterfaceDependencies.IService3")); 179 | } 180 | 181 | [TestMethod] 182 | public void When_Unable_To_Resolve_Non_Nested_Dependency_Should_Include_That_Type_In_The_Exception() 183 | { 184 | var container = UtilityMethods.GetContainer(); 185 | container.Register(); 186 | container.Register(); 187 | container.Register(); 188 | 189 | TinyIoCResolutionException e = null; 190 | try 191 | { 192 | container.Resolve(); 193 | } 194 | catch (TinyIoCResolutionException ex) 195 | { 196 | e = ex; 197 | } 198 | 199 | Assert.IsNotNull(e); 200 | Assert.IsTrue(e.ToString().Contains("NestedInterfaceDependencies.IService1")); 201 | } 202 | 203 | [TestMethod] 204 | public void Run_Platform_Tests() 205 | { 206 | var logger = new StringLogger(); 207 | var platformTests = new PlatformTestSuite.PlatformTests(logger); 208 | 209 | int failed; 210 | int run; 211 | int passed; 212 | platformTests.RunTests(out run, out passed, out failed); 213 | 214 | Assert.AreEqual(0, failed, logger.Log); 215 | } 216 | 217 | [TestMethod] 218 | public void Resolve_InterfacesAcrossInChildContainer_Resolves() 219 | { 220 | var container = UtilityMethods.GetContainer(); 221 | 222 | container.Register().AsMultiInstance(); 223 | 224 | container.Register().AsMultiInstance(); 225 | 226 | container.Register().AsMultiInstance(); 227 | 228 | var child = container.GetChildContainer(); 229 | 230 | var nestedService = new Service3(); 231 | child.Register(nestedService); 232 | 233 | var service5 = child.Resolve(); 234 | 235 | Assert.IsNotNull(service5.Service4); 236 | 237 | Assert.AreSame(nestedService, service5.Service4.Service2.Service3); 238 | } 239 | } 240 | } 241 | -------------------------------------------------------------------------------- /tests/TinyIoC.Tests/TinyMessageSubscriptionTokenTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using TinyIoC.Tests.TestData; 6 | using TinyMessenger; 7 | 8 | #if !NETFX_CORE 9 | using Microsoft.VisualStudio.TestTools.UnitTesting; 10 | #else 11 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 12 | #endif 13 | 14 | namespace TinyIoC.Tests 15 | { 16 | [TestClass] 17 | public class TinyMessageSubscriptionTokenTests 18 | { 19 | #if MOQ 20 | [TestMethod] 21 | public void Dispose_WithValidHubReference_UnregistersWithHub() 22 | { 23 | var messengerMock = new Moq.Mock(); 24 | messengerMock.Setup((messenger) => messenger.Unsubscribe(Moq.It.IsAny())).Verifiable(); 25 | var token = new TinyMessageSubscriptionToken(messengerMock.Object, typeof(TestMessage)); 26 | 27 | token.Dispose(); 28 | 29 | messengerMock.VerifyAll(); 30 | } 31 | #endif 32 | 33 | // can't do GC.WaitForFullGCComplete in WinRT... 34 | #if !NETFX_CORE 35 | [TestMethod] 36 | public void Dispose_WithInvalidHubReference_DoesNotThrow() 37 | { 38 | var token = UtilityMethods.GetTokenWithOutOfScopeMessenger(); 39 | GC.Collect(); 40 | GC.WaitForFullGCComplete(2000); 41 | 42 | token.Dispose(); 43 | } 44 | #endif 45 | 46 | [TestMethod] 47 | //[ExpectedException(typeof(ArgumentNullException))] 48 | public void Ctor_NullHub_ThrowsArgumentNullException() 49 | { 50 | var messenger = UtilityMethods.GetMessenger(); 51 | 52 | AssertHelper.ThrowsException(() => new TinyMessageSubscriptionToken(null, typeof(ITinyMessage))); 53 | } 54 | 55 | [TestMethod] 56 | //[ExpectedException(typeof(ArgumentOutOfRangeException))] 57 | public void Ctor_InvalidMessageType_ThrowsArgumentOutOfRangeException() 58 | { 59 | var messenger = UtilityMethods.GetMessenger(); 60 | 61 | AssertHelper.ThrowsException(() => new TinyMessageSubscriptionToken(messenger, typeof(object))); 62 | } 63 | 64 | [TestMethod] 65 | public void Ctor_ValidHubAndMessageType_DoesNotThrow() 66 | { 67 | var messenger = UtilityMethods.GetMessenger(); 68 | 69 | var token = new TinyMessageSubscriptionToken(messenger, typeof(TestMessage)); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /tests/TinyIoC.Tests/TinyMessengerTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using TinyIoC.Tests.TestData; 6 | using TinyMessenger; 7 | using System.Threading; 8 | 9 | #if !NETFX_CORE 10 | using Microsoft.VisualStudio.TestTools.UnitTesting; 11 | #else 12 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 13 | #endif 14 | 15 | namespace TinyIoC.Tests 16 | { 17 | [TestClass] 18 | public class TinyMessengerTests 19 | { 20 | [TestMethod] 21 | public void TinyMessenger_Ctor_DoesNotThrow() 22 | { 23 | var messenger = UtilityMethods.GetMessenger(); 24 | } 25 | 26 | [TestMethod] 27 | public void Subscribe_ValidDeliverAction_DoesNotThrow() 28 | { 29 | var messenger = UtilityMethods.GetMessenger(); 30 | 31 | messenger.Subscribe(new Action(UtilityMethods.FakeDeliveryAction)); 32 | } 33 | 34 | [TestMethod] 35 | public void SubScribe_ValidDeliveryAction_ReturnsRegistrationObject() 36 | { 37 | var messenger = UtilityMethods.GetMessenger(); 38 | 39 | var output = messenger.Subscribe(new Action(UtilityMethods.FakeDeliveryAction)); 40 | 41 | Assert.IsInstanceOfType(output, typeof(TinyMessageSubscriptionToken)); 42 | } 43 | 44 | [TestMethod] 45 | public void Subscribe_ValidDeliverActionWIthStrongReferences_DoesNotThrow() 46 | { 47 | var messenger = UtilityMethods.GetMessenger(); 48 | 49 | messenger.Subscribe(new Action(UtilityMethods.FakeDeliveryAction), true); 50 | } 51 | 52 | [TestMethod] 53 | public void Subscribe_ValidDeliveryActionAndFilter_DoesNotThrow() 54 | { 55 | var messenger = UtilityMethods.GetMessenger(); 56 | 57 | messenger.Subscribe(new Action(UtilityMethods.FakeDeliveryAction), new Func(UtilityMethods.FakeMessageFilter)); 58 | } 59 | 60 | [TestMethod] 61 | //[ExpectedException(typeof(ArgumentNullException))] 62 | public void Subscribe_NullDeliveryAction_Throws() 63 | { 64 | var messenger = UtilityMethods.GetMessenger(); 65 | 66 | AssertHelper.ThrowsException(() => messenger.Subscribe(null, new Func(UtilityMethods.FakeMessageFilter))); 67 | } 68 | 69 | [TestMethod] 70 | //[ExpectedException(typeof(ArgumentNullException))] 71 | public void Subscribe_NullFilter_Throws() 72 | { 73 | var messenger = UtilityMethods.GetMessenger(); 74 | 75 | AssertHelper.ThrowsException(() => messenger.Subscribe(new Action(UtilityMethods.FakeDeliveryAction), null, new TestProxy())); 76 | } 77 | 78 | [TestMethod] 79 | //[ExpectedException(typeof(ArgumentNullException))] 80 | public void Subscribe_NullProxy_Throws() 81 | { 82 | var messenger = UtilityMethods.GetMessenger(); 83 | 84 | AssertHelper.ThrowsException(() => messenger.Subscribe(new Action(UtilityMethods.FakeDeliveryAction), new Func(UtilityMethods.FakeMessageFilter), null)); 85 | } 86 | 87 | [TestMethod] 88 | //[ExpectedException(typeof(ArgumentNullException))] 89 | public void Unsubscribe_NullSubscriptionObject_Throws() 90 | { 91 | var messenger = UtilityMethods.GetMessenger(); 92 | 93 | AssertHelper.ThrowsException(() => messenger.Unsubscribe(null)); 94 | } 95 | 96 | [TestMethod] 97 | public void Unsubscribe_PreviousSubscription_DoesNotThrow() 98 | { 99 | var messenger = UtilityMethods.GetMessenger(); 100 | var subscription = messenger.Subscribe(new Action(UtilityMethods.FakeDeliveryAction), new Func(UtilityMethods.FakeMessageFilter)); 101 | 102 | messenger.Unsubscribe(subscription); 103 | } 104 | 105 | [TestMethod] 106 | public void Subscribe_PreviousSubscription_ReturnsDifferentSubscriptionObject() 107 | { 108 | var messenger = UtilityMethods.GetMessenger(); 109 | var sub1 = messenger.Subscribe(new Action(UtilityMethods.FakeDeliveryAction), new Func(UtilityMethods.FakeMessageFilter)); 110 | var sub2 = messenger.Subscribe(new Action(UtilityMethods.FakeDeliveryAction), new Func(UtilityMethods.FakeMessageFilter)); 111 | 112 | Assert.IsFalse(object.ReferenceEquals(sub1, sub2)); 113 | } 114 | 115 | [TestMethod] 116 | public void Subscribe_CustomProxyNoFilter_DoesNotThrow() 117 | { 118 | var messenger = UtilityMethods.GetMessenger(); 119 | var proxy = new TestProxy(); 120 | 121 | messenger.Subscribe(new Action(UtilityMethods.FakeDeliveryAction), proxy); 122 | } 123 | 124 | [TestMethod] 125 | public void Subscribe_CustomProxyWithFilter_DoesNotThrow() 126 | { 127 | var messenger = UtilityMethods.GetMessenger(); 128 | var proxy = new TestProxy(); 129 | 130 | messenger.Subscribe(new Action(UtilityMethods.FakeDeliveryAction), new Func(UtilityMethods.FakeMessageFilter), proxy); 131 | } 132 | 133 | [TestMethod] 134 | public void Subscribe_CustomProxyNoFilterStrongReference_DoesNotThrow() 135 | { 136 | var messenger = UtilityMethods.GetMessenger(); 137 | var proxy = new TestProxy(); 138 | 139 | messenger.Subscribe(new Action(UtilityMethods.FakeDeliveryAction), true, proxy); 140 | } 141 | 142 | [TestMethod] 143 | public void Subscribe_CustomProxyFilterStrongReference_DoesNotThrow() 144 | { 145 | var messenger = UtilityMethods.GetMessenger(); 146 | var proxy = new TestProxy(); 147 | 148 | messenger.Subscribe(new Action(UtilityMethods.FakeDeliveryAction), new Func(UtilityMethods.FakeMessageFilter), true, proxy); 149 | } 150 | 151 | [TestMethod] 152 | public void Publish_CustomProxyNoFilter_UsesCorrectProxy() 153 | { 154 | var messenger = UtilityMethods.GetMessenger(); 155 | var proxy = new TestProxy(); 156 | messenger.Subscribe(new Action(UtilityMethods.FakeDeliveryAction), proxy); 157 | var message = new TestMessage(this); 158 | 159 | messenger.Publish(message); 160 | 161 | Assert.AreSame(message, proxy.Message); 162 | } 163 | 164 | [TestMethod] 165 | public void Publish_CustomProxyWithFilter_UsesCorrectProxy() 166 | { 167 | var messenger = UtilityMethods.GetMessenger(); 168 | var proxy = new TestProxy(); 169 | messenger.Subscribe(new Action(UtilityMethods.FakeDeliveryAction), new Func(UtilityMethods.FakeMessageFilter), proxy); 170 | var message = new TestMessage(this); 171 | 172 | messenger.Publish(message); 173 | 174 | Assert.AreSame(message, proxy.Message); 175 | } 176 | 177 | [TestMethod] 178 | public void Publish_CustomProxyNoFilterStrongReference_UsesCorrectProxy() 179 | { 180 | var messenger = UtilityMethods.GetMessenger(); 181 | var proxy = new TestProxy(); 182 | messenger.Subscribe(new Action(UtilityMethods.FakeDeliveryAction), true, proxy); 183 | var message = new TestMessage(this); 184 | 185 | messenger.Publish(message); 186 | 187 | Assert.AreSame(message, proxy.Message); 188 | } 189 | 190 | [TestMethod] 191 | public void Publish_CustomProxyFilterStrongReference_UsesCorrectProxy() 192 | { 193 | var messenger = UtilityMethods.GetMessenger(); 194 | var proxy = new TestProxy(); 195 | messenger.Subscribe(new Action(UtilityMethods.FakeDeliveryAction), new Func(UtilityMethods.FakeMessageFilter), true, proxy); 196 | var message = new TestMessage(this); 197 | 198 | messenger.Publish(message); 199 | 200 | Assert.AreSame(message, proxy.Message); 201 | } 202 | 203 | [TestMethod] 204 | //[ExpectedException(typeof(ArgumentNullException))] 205 | public void Publish_NullMessage_Throws() 206 | { 207 | var messenger = UtilityMethods.GetMessenger(); 208 | 209 | AssertHelper.ThrowsException(() => messenger.Publish(null)); 210 | } 211 | 212 | [TestMethod] 213 | public void Publish_NoSubscribers_DoesNotThrow() 214 | { 215 | var messenger = UtilityMethods.GetMessenger(); 216 | 217 | messenger.Publish(new TestMessage(this)); 218 | } 219 | 220 | [TestMethod] 221 | public void Publish_Subscriber_DoesNotThrow() 222 | { 223 | var messenger = UtilityMethods.GetMessenger(); 224 | messenger.Subscribe(new Action(UtilityMethods.FakeDeliveryAction), new Func(UtilityMethods.FakeMessageFilter)); 225 | 226 | messenger.Publish(new TestMessage(this)); 227 | } 228 | 229 | [TestMethod] 230 | public void Publish_SubscribedMessageNoFilter_GetsMessage() 231 | { 232 | var messenger = UtilityMethods.GetMessenger(); 233 | bool received = false; 234 | messenger.Subscribe((m) => { received = true; }); 235 | 236 | messenger.Publish(new TestMessage(this)); 237 | 238 | Assert.IsTrue(received); 239 | } 240 | 241 | [TestMethod] 242 | public void Publish_SubscribedThenUnsubscribedMessageNoFilter_DoesNotGetMessage() 243 | { 244 | var messenger = UtilityMethods.GetMessenger(); 245 | bool received = false; 246 | var token = messenger.Subscribe((m) => { received = true; }); 247 | messenger.Unsubscribe(token); 248 | 249 | messenger.Publish(new TestMessage(this)); 250 | 251 | Assert.IsFalse(received); 252 | } 253 | 254 | [TestMethod] 255 | public void Publish_SubscribedMessageButFiltered_DoesNotGetMessage() 256 | { 257 | var messenger = UtilityMethods.GetMessenger(); 258 | bool received = false; 259 | messenger.Subscribe((m) => { received = true; }, (m) => false); 260 | 261 | messenger.Publish(new TestMessage(this)); 262 | 263 | Assert.IsFalse(received); 264 | } 265 | 266 | [TestMethod] 267 | public void Publish_SubscribedMessageNoFilter_GetsActualMessage() 268 | { 269 | var messenger = UtilityMethods.GetMessenger(); 270 | ITinyMessage receivedMessage = null; 271 | var payload = new TestMessage(this); 272 | messenger.Subscribe((m) => { receivedMessage = m; }); 273 | 274 | messenger.Publish(payload); 275 | 276 | Assert.AreSame(payload, receivedMessage); 277 | } 278 | 279 | [TestMethod] 280 | public void GenericTinyMessage_String_SubscribeDoesNotThrow() 281 | { 282 | var messenger = UtilityMethods.GetMessenger(); 283 | var output = string.Empty; 284 | messenger.Subscribe>((m) => { output = m.Content; }); 285 | } 286 | 287 | [TestMethod] 288 | public void GenericTinyMessage_String_PubishDoesNotThrow() 289 | { 290 | var messenger = UtilityMethods.GetMessenger(); 291 | messenger.Publish(new GenericTinyMessage(this, "Testing")); 292 | } 293 | 294 | [TestMethod] 295 | public void GenericTinyMessage_String_PubishAndSubscribeDeliversContent() 296 | { 297 | var messenger = UtilityMethods.GetMessenger(); 298 | var output = string.Empty; 299 | messenger.Subscribe>((m) => { output = m.Content; }); 300 | messenger.Publish(new GenericTinyMessage(this, "Testing")); 301 | 302 | Assert.AreEqual("Testing", output); 303 | } 304 | 305 | [TestMethod] 306 | public void Publish_SubscriptionThrowingException_DoesNotThrow() 307 | { 308 | var messenger = UtilityMethods.GetMessenger(); 309 | messenger.Subscribe>((m) => { throw new NotImplementedException(); }); 310 | 311 | messenger.Publish(new GenericTinyMessage(this, "Testing")); 312 | } 313 | 314 | [TestMethod] 315 | public void PublishAsync_NoCallback_DoesNotThrow() 316 | { 317 | var messenger = UtilityMethods.GetMessenger(); 318 | 319 | messenger.PublishAsync(new TestMessage(this)); 320 | } 321 | 322 | [TestMethod] 323 | public void PublishAsync_Callback_EventOnce() 324 | { 325 | var syncRoot = new object(); 326 | var messageCount = 0; 327 | var callbackEvent = new ManualResetEvent(false); 328 | 329 | var messenger = UtilityMethods.GetMessenger(); 330 | messenger.Subscribe(m => { lock (syncRoot) messageCount++; }); 331 | var message = new TestMessage(this); 332 | 333 | messenger.PublishAsync(message, ar => callbackEvent.Set()); 334 | 335 | Assert.IsTrue(callbackEvent.WaitOne(1000)); 336 | Assert.AreEqual(1, messageCount); 337 | } 338 | 339 | [TestMethod] 340 | public void PublishAsync_NoCallback_PublishesMessage() 341 | { 342 | var messenger = UtilityMethods.GetMessenger(); 343 | var received = new ManualResetEvent(false); 344 | messenger.Subscribe(m => received.Set()); 345 | 346 | messenger.PublishAsync(new TestMessage(this)); 347 | 348 | Assert.IsTrue(received.WaitOne(1000)); 349 | } 350 | 351 | [TestMethod] 352 | public void PublishAsync_Callback_DoesNotThrow() 353 | { 354 | var messenger = UtilityMethods.GetMessenger(); 355 | #pragma warning disable 219 356 | messenger.PublishAsync(new TestMessage(this), (r) => {string test = "Testing";}); 357 | #pragma warning restore 219 358 | } 359 | 360 | [TestMethod] 361 | public void PublishAsync_Callback_PublishesMessage() 362 | { 363 | var messenger = UtilityMethods.GetMessenger(); 364 | var received = new ManualResetEvent(false); 365 | messenger.Subscribe(m => received.Set()); 366 | 367 | #pragma warning disable 219 368 | messenger.PublishAsync(new TestMessage(this), (r) => { string test = "Testing"; }); 369 | #pragma warning restore 219 370 | 371 | Assert.IsTrue(received.WaitOne(1000)); 372 | } 373 | 374 | [TestMethod] 375 | public void PublishAsync_Callback_CallsCallback() 376 | { 377 | var messenger = UtilityMethods.GetMessenger(); 378 | var received = new ManualResetEvent(false); 379 | var callbackReceived = new ManualResetEvent(false); 380 | messenger.Subscribe(m => received.Set()); 381 | 382 | messenger.PublishAsync(new TestMessage(this), r => callbackReceived.Set()); 383 | 384 | Assert.IsTrue(callbackReceived.WaitOne(1000)); 385 | Assert.IsTrue(received.WaitOne(0)); 386 | } 387 | 388 | [TestMethod] 389 | public void CancellableGenericTinyMessage_Publish_DoesNotThrow() 390 | { 391 | var messenger = UtilityMethods.GetMessenger(); 392 | #pragma warning disable 219 393 | messenger.Publish>(new CancellableGenericTinyMessage(this, "Testing", () => { bool test = true; })); 394 | #pragma warning restore 219 395 | } 396 | 397 | [TestMethod] 398 | //[ExpectedException(typeof(ArgumentNullException))] 399 | public void CancellableGenericTinyMessage_PublishWithNullAction_Throws() 400 | { 401 | var messenger = UtilityMethods.GetMessenger(); 402 | AssertHelper.ThrowsException(() => messenger.Publish>(new CancellableGenericTinyMessage(this, "Testing", null))); 403 | } 404 | 405 | [TestMethod] 406 | public void CancellableGenericTinyMessage_SubscriberCancels_CancelActioned() 407 | { 408 | var messenger = UtilityMethods.GetMessenger(); 409 | bool cancelled = false; 410 | messenger.Subscribe>((m) => { m.Cancel(); }); 411 | 412 | messenger.Publish>(new CancellableGenericTinyMessage(this, "Testing", () => { cancelled = true; })); 413 | 414 | Assert.IsTrue(cancelled); 415 | } 416 | 417 | [TestMethod] 418 | public void CancellableGenericTinyMessage_SeveralSubscribersOneCancels_CancelActioned() 419 | { 420 | var messenger = UtilityMethods.GetMessenger(); 421 | bool cancelled = false; 422 | #pragma warning disable 219 423 | messenger.Subscribe>((m) => { var test = 1; }); 424 | messenger.Subscribe>((m) => { m.Cancel(); }); 425 | messenger.Subscribe>((m) => { var test = 1; }); 426 | #pragma warning restore 219 427 | messenger.Publish>(new CancellableGenericTinyMessage(this, "Testing", () => { cancelled = true; })); 428 | 429 | Assert.IsTrue(cancelled); 430 | } 431 | } 432 | } -------------------------------------------------------------------------------- /tests/TinyIoC.Tests/TypeExtensionsTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Reflection; 6 | 7 | #if !NETFX_CORE 8 | using Microsoft.VisualStudio.TestTools.UnitTesting; 9 | #else 10 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 11 | #endif 12 | 13 | namespace TinyIoC.Tests.TypeExtensions 14 | { 15 | public interface ITestInterface 16 | { 17 | } 18 | 19 | public class ClassImplementingITestInterface : ITestInterface 20 | { 21 | } 22 | 23 | public class AnotherClassImplementingITestInterface : ITestInterface 24 | { 25 | 26 | } 27 | 28 | public class ClassNotImplementingITestInterface 29 | { 30 | } 31 | 32 | [TestClass] 33 | public class TypeExtensionsTests 34 | { 35 | [TestMethod] 36 | public void GetGenericMethod_RegisterOneGenericParameterNoParameters_ReturnsCorrectMethod() 37 | { 38 | var firstGenericParameter = typeof(ClassNotImplementingITestInterface); 39 | 40 | var method = typeof(TinyIoCContainer).GetGenericMethod( 41 | BindingFlags.Public | BindingFlags.Instance, 42 | "Register", 43 | new Type[] {firstGenericParameter}, 44 | new Type[] { } 45 | ); 46 | 47 | Assert.IsInstanceOfType(method, typeof(MethodInfo)); 48 | Assert.IsTrue(method.IsGenericMethod); 49 | Assert.AreEqual(0, method.GetParameters().Length); 50 | Assert.AreEqual(1, method.GetGenericArguments().Length); 51 | Assert.AreEqual(firstGenericParameter, method.GetGenericArguments()[0]); 52 | } 53 | 54 | [TestMethod] 55 | public void GetGenericMethod_RegisterTwoAcceptableGenericParameterNoParameters_ReturnsCorrectMethod() 56 | { 57 | var firstGenericParameter = typeof(ITestInterface); 58 | var secondGenericParameter = typeof(ClassImplementingITestInterface); 59 | 60 | var method = typeof(TinyIoCContainer).GetGenericMethod( 61 | BindingFlags.Public | BindingFlags.Instance, 62 | "Register", 63 | new Type[] { firstGenericParameter, secondGenericParameter }, 64 | new Type[] { } 65 | ); 66 | 67 | Assert.IsInstanceOfType(method, typeof(MethodInfo)); 68 | Assert.IsTrue(method.IsGenericMethod); 69 | Assert.AreEqual(0, method.GetParameters().Length); 70 | Assert.AreEqual(2, method.GetGenericArguments().Length); 71 | Assert.AreEqual(firstGenericParameter, method.GetGenericArguments()[0]); 72 | Assert.AreEqual(secondGenericParameter, method.GetGenericArguments()[1]); 73 | } 74 | 75 | [TestMethod] 76 | public void GetGenericMethod_TwiceWithDifferentGenericParamters_ReturnsCorrectMethods() 77 | { 78 | var methodOneFirstGenericParameter = typeof(ITestInterface); 79 | var methodOneSecondGenericParameter = typeof(ClassImplementingITestInterface); 80 | var methodTwoFirstGenericParameter = typeof(ITestInterface); 81 | var methodTwoSecondGenericParameter = typeof(AnotherClassImplementingITestInterface); 82 | 83 | var methodOne = typeof(TinyIoCContainer).GetGenericMethod( 84 | BindingFlags.Public | BindingFlags.Instance, 85 | "Register", 86 | new Type[] { methodOneFirstGenericParameter, methodOneSecondGenericParameter }, 87 | new Type[] { }); 88 | var methodTwo = typeof(TinyIoCContainer).GetGenericMethod( 89 | BindingFlags.Public | BindingFlags.Instance, 90 | "Register", 91 | new Type[] { methodTwoFirstGenericParameter, methodTwoSecondGenericParameter }, 92 | new Type[] { }); 93 | 94 | Assert.IsInstanceOfType(methodOne, typeof(MethodInfo)); 95 | Assert.IsTrue(methodOne.IsGenericMethod); 96 | Assert.AreEqual(0, methodOne.GetParameters().Length); 97 | Assert.AreEqual(2, methodOne.GetGenericArguments().Length); 98 | Assert.AreEqual(methodOneFirstGenericParameter, methodOne.GetGenericArguments()[0]); 99 | Assert.AreEqual(methodOneSecondGenericParameter, methodOne.GetGenericArguments()[1]); 100 | Assert.IsInstanceOfType(methodTwo, typeof(MethodInfo)); 101 | Assert.IsTrue(methodTwo.IsGenericMethod); 102 | Assert.AreEqual(0, methodTwo.GetParameters().Length); 103 | Assert.AreEqual(2, methodTwo.GetGenericArguments().Length); 104 | Assert.AreEqual(methodTwoFirstGenericParameter, methodTwo.GetGenericArguments()[0]); 105 | Assert.AreEqual(methodTwoSecondGenericParameter, methodTwo.GetGenericArguments()[1]); 106 | } 107 | 108 | [TestMethod] 109 | public void GetGenericMethod_RegisterTwoUnacceptableGenericParameterNoParameters_Throws() 110 | { 111 | try 112 | { 113 | var method = typeof(TinyIoCContainer).GetGenericMethod( 114 | BindingFlags.Public | BindingFlags.Instance, 115 | "Register", 116 | new Type[] { typeof(ITestInterface), typeof(ClassNotImplementingITestInterface) }, 117 | new Type[] { } 118 | ); 119 | 120 | Assert.Fail(); 121 | } 122 | catch (System.ArgumentException) 123 | { 124 | } 125 | } 126 | 127 | [TestMethod] 128 | public void GetGenericMethod_RegisterTwoAcceptableGenericParameterMethodParameters_ReturnsCorrectMethod() 129 | { 130 | var firstGenericParameter = typeof(ITestInterface); 131 | var secondGenericParameter = typeof(ClassImplementingITestInterface); 132 | var firstParameter = typeof(string); 133 | 134 | var method = typeof(TinyIoCContainer).GetGenericMethod( 135 | BindingFlags.Public | BindingFlags.Instance, 136 | "Register", 137 | new Type[] { firstGenericParameter, secondGenericParameter }, 138 | new Type[] { firstParameter } 139 | ); 140 | 141 | Assert.IsInstanceOfType(method, typeof(MethodInfo)); 142 | Assert.IsTrue(method.IsGenericMethod); 143 | Assert.AreEqual(1, method.GetParameters().Length); 144 | Assert.AreEqual(firstParameter, method.GetParameters()[0].ParameterType); 145 | Assert.AreEqual(2, method.GetGenericArguments().Length); 146 | Assert.AreEqual(firstGenericParameter, method.GetGenericArguments()[0]); 147 | Assert.AreEqual(secondGenericParameter, method.GetGenericArguments()[1]); 148 | } 149 | 150 | [TestMethod] 151 | public void GetGenericMethod_RegisterWithGenericTypeAsAMethodParameter_ReturnsCorrectMethod() 152 | { 153 | var firstGenericParameter = typeof(ITestInterface); 154 | var secondGenericParameter = typeof(ClassImplementingITestInterface); 155 | var firstParameter = typeof(ClassImplementingITestInterface); 156 | 157 | var method = typeof(TinyIoCContainer).GetGenericMethod( 158 | BindingFlags.Public | BindingFlags.Instance, 159 | "Register", 160 | new Type[] { firstGenericParameter, secondGenericParameter }, 161 | new Type[] { firstParameter } 162 | ); 163 | 164 | Assert.IsInstanceOfType(method, typeof(MethodInfo)); 165 | Assert.IsTrue(method.IsGenericMethod); 166 | Assert.AreEqual(1, method.GetParameters().Length); 167 | Assert.AreEqual(firstParameter, method.GetParameters()[0].ParameterType); 168 | Assert.AreEqual(2, method.GetGenericArguments().Length); 169 | Assert.AreEqual(firstGenericParameter, method.GetGenericArguments()[0]); 170 | Assert.AreEqual(secondGenericParameter, method.GetGenericArguments()[1]); 171 | } 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /tests/TinyIoc.Benchmarks/AutoRegisterBenchmarks.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using BenchmarkDotNet.Attributes; 5 | 6 | namespace TinyIoc.Benchmarks 7 | { 8 | 9 | #if NET48 //These work on either platform but no point running them twice 10 | [SimpleJob(BenchmarkDotNet.Jobs.RuntimeMoniker.Net48)] 11 | [SimpleJob(BenchmarkDotNet.Jobs.RuntimeMoniker.Net461)] 12 | #endif 13 | #if NETCOREAPP3_1_OR_GREATER // These don't seem to work in a FX app 14 | [SimpleJob(BenchmarkDotNet.Jobs.RuntimeMoniker.NetCoreApp31)] 15 | [RyuJitX86Job] 16 | #endif 17 | #if NET48 //These don't seem to work in a .net core app 18 | [RyuJitX64Job] 19 | [MonoJob] 20 | #endif 21 | [MemoryDiagnoser] 22 | public class AutoRegisterBenchmarks 23 | { 24 | 25 | [BenchmarkCategory("AutoResolve"), Benchmark(Baseline = true)] 26 | public TinyIoC.Original.TinyIoCContainer Original_AutoRegister() 27 | { 28 | var retVal = new TinyIoC.Original.TinyIoCContainer(); 29 | retVal.AutoRegister(); 30 | return retVal; 31 | } 32 | 33 | [BenchmarkCategory("AutoResolve"), Benchmark] 34 | public TinyIoC.TinyIoCContainer New_AutoRegister() 35 | { 36 | var retVal = new TinyIoC.TinyIoCContainer(); 37 | retVal.AutoRegister(); 38 | return retVal; 39 | } 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/TinyIoc.Benchmarks/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BenchmarkDotNet.Running; 3 | 4 | namespace TinyIoc.Benchmarks 5 | { 6 | class Program 7 | { 8 | static void Main(string[] args) 9 | { 10 | BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/TinyIoc.Benchmarks/ResolveBenchmarks.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using BenchmarkDotNet.Attributes; 5 | 6 | namespace TinyIoc.Benchmarks 7 | { 8 | 9 | #if NET48 //These work on either platform but no point running them twice 10 | [SimpleJob(BenchmarkDotNet.Jobs.RuntimeMoniker.Net48)] 11 | [SimpleJob(BenchmarkDotNet.Jobs.RuntimeMoniker.Net461)] 12 | #endif 13 | #if NETCOREAPP3_1_OR_GREATER // These don't seem to work in a FX app 14 | [SimpleJob(BenchmarkDotNet.Jobs.RuntimeMoniker.NetCoreApp31)] 15 | [RyuJitX86Job] 16 | #endif 17 | #if NET48 //These don't seem to work in a .net core app 18 | [RyuJitX64Job] 19 | [MonoJob] 20 | #endif 21 | [MemoryDiagnoser] 22 | [GroupBenchmarksBy(BenchmarkDotNet.Configs.BenchmarkLogicalGroupRule.ByCategory)] 23 | //[CategoriesColumn] 24 | public class ResolveBenchmarks 25 | { 26 | private TinyIoC.TinyIoCContainer _NewContainer; 27 | private TinyIoC.Original.TinyIoCContainer _OriginalContainer; 28 | 29 | [BenchmarkDotNet.Attributes.GlobalSetup] 30 | public void InitContainer() 31 | { 32 | _NewContainer = new TinyIoC.TinyIoCContainer(); 33 | _NewContainer.Register().AsSingleton(); 34 | _NewContainer.Register().AsMultiInstance(); 35 | _NewContainer.Register().AsMultiInstance(); 36 | _NewContainer.Register(typeof(IOpenGeneric<>), typeof(OpenGenericInstance<>)).AsMultiInstance(); 37 | 38 | _OriginalContainer = new TinyIoC.Original.TinyIoCContainer(); 39 | _OriginalContainer.Register().AsSingleton(); 40 | _OriginalContainer.Register().AsMultiInstance(); 41 | _OriginalContainer.Register().AsMultiInstance(); 42 | _OriginalContainer.Register(typeof(IOpenGeneric<>), typeof(OpenGenericInstance<>)).AsMultiInstance(); 43 | } 44 | 45 | [BenchmarkCategory("ResolveSingleton"), Benchmark(Baseline = true)] 46 | public ISingleton Original_Resolve_Singleton() 47 | { 48 | return _OriginalContainer.Resolve(); 49 | } 50 | 51 | [BenchmarkCategory("ResolveSingleton"), Benchmark] 52 | public ISingleton New_Resolve_Singleton() 53 | { 54 | return _NewContainer.Resolve(); 55 | } 56 | 57 | 58 | [BenchmarkCategory("ResolveInstance"), Benchmark(Baseline = true)] 59 | public IParameterlessInstance Original_Resolve_Instance_Without_Dependencies() 60 | { 61 | return _OriginalContainer.Resolve(); 62 | } 63 | 64 | [BenchmarkCategory("ResolveInstance"), Benchmark] 65 | public IParameterlessInstance New_Resolve_Instance_Without_Dependencies() 66 | { 67 | return _NewContainer.Resolve(); 68 | } 69 | 70 | 71 | [BenchmarkCategory("ResolveInstanceWithSingletonDependency"), Benchmark(Baseline = true)] 72 | public ISingleParameterInstance Original_Resolve_Instance_With_Singleton_Dependency() 73 | { 74 | return _OriginalContainer.Resolve(); 75 | } 76 | 77 | [BenchmarkCategory("ResolveInstanceWithSingletonDependency"), Benchmark] 78 | public ISingleParameterInstance New_Resolve_Instance_With_Singleton_Dependency() 79 | { 80 | return _NewContainer.Resolve(); 81 | } 82 | 83 | 84 | [BenchmarkCategory("ResolveOpenGeneric"), Benchmark(Baseline = true)] 85 | public IOpenGeneric Original_Resolve_OpenGeneric() 86 | { 87 | return _OriginalContainer.Resolve>(); 88 | } 89 | 90 | [BenchmarkCategory("ResolveOpenGeneric"), Benchmark] 91 | public IOpenGeneric New_Resolve_OpenGeneric() 92 | { 93 | return _NewContainer.Resolve>(); 94 | } 95 | 96 | 97 | [BenchmarkCategory("ResolveUnregistered"), Benchmark(Baseline = true)] 98 | public UnregisteredInstance Original_Resolve_Unregistered() 99 | { 100 | return _OriginalContainer.Resolve(); 101 | } 102 | 103 | [BenchmarkCategory("ResolveUnregistered"), Benchmark] 104 | public UnregisteredInstance New_Resolve_Unregistered() 105 | { 106 | return _NewContainer.Resolve(); 107 | } 108 | 109 | 110 | [BenchmarkCategory("AutomaticFuncFactory"), Benchmark(Baseline = true)] 111 | public Func Original_Resolve_AutomaticFuncFactory() 112 | { 113 | return _OriginalContainer.Resolve>(); 114 | } 115 | 116 | [BenchmarkCategory("AutomaticFuncFactory"), Benchmark] 117 | public Func New_Resolve_AutomaticFuncFactory() 118 | { 119 | return _NewContainer.Resolve>(); 120 | } 121 | } 122 | 123 | public interface ISingleton 124 | { 125 | 126 | } 127 | 128 | public class Singleton : ISingleton 129 | { 130 | public Singleton() 131 | { 132 | 133 | } 134 | } 135 | 136 | public interface IParameterlessInstance { } 137 | 138 | public class ParameterlessInstance : IParameterlessInstance { } 139 | 140 | public class UnregisteredInstance { public UnregisteredInstance(ISingleton singleton) {} } 141 | 142 | public interface ISingleParameterInstance { } 143 | 144 | public class SingleParameterInstance : ISingleParameterInstance 145 | { 146 | private readonly ISingleton _Singleton; 147 | public SingleParameterInstance(ISingleton singleton) 148 | { 149 | _Singleton = singleton; 150 | } 151 | } 152 | 153 | public interface IOpenGeneric { T Value { get; set; } } 154 | public class OpenGenericInstance : IOpenGeneric 155 | { 156 | public T Value { get; set; } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /tests/TinyIoc.Benchmarks/TinyIoc.Benchmarks.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp3.1;net48;net461 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | --------------------------------------------------------------------------------