├── .gitattributes ├── .gitignore ├── CONTRIBUTING.md ├── COPYING ├── LICENSE.md ├── README.md ├── appveyor.yml ├── build.cake ├── build.ps1 └── src ├── Reactive.EventAggregator.Tests ├── Reactive.EventAggregator.Tests.csproj └── SimpleTests.cs ├── Reactive.EventAggregator.sln ├── Reactive.EventAggregator.sln.DotSettings └── Reactive.EventAggregator ├── EventAggregator.cs ├── IEventAggregator.cs └── Reactive.EventAggregator.csproj /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 2 | bin 3 | obj 4 | packages 5 | 6 | # mstest test results 7 | TestResults 8 | 9 | *.csproj.user 10 | *.suo 11 | 12 | *ncrunch* 13 | 14 | *.nupkg 15 | 16 | # CAKE build tools 17 | tools 18 | 19 | .vs/ -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | ## Prerequisites 4 | 5 | You need Visual Studio 2017 to open this solution. You can download the 6 | Community Edition from [here](https://www.visualstudio.com/downloads/). 7 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 GitHub, Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a 4 | copy of this software and associated documentation files (the "Software"), 5 | to deal in the Software without restriction, including without limitation 6 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | and/or sell copies of the Software, and to permit persons to whom the 8 | Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | DEALINGS IN THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiftkey/Reactive.EventAggregator/8d0d731db064f33ad899b407c9810aef83601301/LICENSE.md -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Reactive.EventAggregator 2 | 3 | This is an update of a blog post from José F. Romaniello about using Reactive Extensions to implement an event aggregator. [source](http://joseoncode.com/2010/04/29/event-aggregator-with-reactive-extensions/) 4 | 5 | [![Build status](https://ci.appveyor.com/api/projects/status/b0yt9pn5njghikr2)](https://ci.appveyor.com/project/shiftkey/reactive-eventaggregator) 6 | 7 | ### Usage 8 | 9 | To install it, just run this from the Package Manager Console: 10 | 11 | Install-Package Reactive.EventAggregator 12 | 13 | ### Why bring it back? 14 | 15 | Three reasons: 16 | 17 | - I wanted a simple event aggregator, without taking a dependency on an MVVM framework 18 | - It should be available on NuGet 19 | - Demonstrate .NET Standard and targetting different platforms from one codebase 20 | 21 | ### Samples 22 | 23 | #### Subscribing to an event 24 | 25 | // arrange 26 | var eventWasRaised = false; 27 | var eventPublisher = new EventAggregator(); 28 | 29 | // act 30 | eventPublisher.GetEvent() 31 | .Subscribe(se => eventWasRaised = true); 32 | 33 | eventPublisher.Publish(new SampleEvent()); 34 | 35 | // assert 36 | eventWasRaised.ShouldBe(true); 37 | 38 | #### Disposing of the event 39 | 40 | // arrange 41 | var eventWasRaised = false; 42 | var eventPublisher = new EventAggregator(); 43 | 44 | // act 45 | var subscription = eventPublisher.GetEvent() 46 | .Subscribe(se => eventWasRaised = true); 47 | 48 | subscription.Dispose(); 49 | eventPublisher.Publish(new SampleEvent()); 50 | 51 | // assert 52 | eventWasRaised.ShouldBe(false); 53 | 54 | #### Selectively subscribing to an event 55 | 56 | // arrange 57 | var eventWasRaised = false; 58 | var eventPublisher = new EventAggregator(); 59 | 60 | // act 61 | eventPublisher.GetEvent() 62 | .Where(se => se.Status == 1) 63 | .Subscribe(se => eventWasRaised = true); 64 | 65 | eventPublisher.Publish(new SampleEvent { Status = 1 }); 66 | 67 | // assert 68 | eventWasRaised.ShouldBe(true); 69 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | image: Visual Studio 2017 2 | 3 | skip_branch_with_pr: true 4 | 5 | environment: 6 | VERSION: 4.0.0 7 | 8 | cache: 9 | - tools -> build.ps1 10 | 11 | build_script: 12 | - ps: .\build.ps1 13 | 14 | test: off 15 | 16 | artifacts: 17 | - path: 'src\**\*.nupkg' -------------------------------------------------------------------------------- /build.cake: -------------------------------------------------------------------------------- 1 | #tool nuget:?package=xunit.runner.console&version=2.1.0 2 | ////////////////////////////////////////////////////////////////////// 3 | // ARGUMENTS 4 | ////////////////////////////////////////////////////////////////////// 5 | 6 | var target = Argument("target", "Default"); 7 | var configuration = Argument("configuration", "Release"); 8 | 9 | ////////////////////////////////////////////////////////////////////// 10 | // PREPARATION 11 | ////////////////////////////////////////////////////////////////////// 12 | 13 | // Define directories. 14 | var buildDir = Directory("./src/Reactive.EventAggregator/Reactive.EventAggregator/bin") + Directory(configuration); 15 | 16 | var version = EnvironmentVariable("VERSION") ?? "3.99.99-rc"; 17 | 18 | ////////////////////////////////////////////////////////////////////// 19 | // TASKS 20 | ////////////////////////////////////////////////////////////////////// 21 | 22 | Task("Clean") 23 | .Does(() => 24 | { 25 | CleanDirectory(buildDir); 26 | }); 27 | 28 | Task("Restore-NuGet-Packages") 29 | .IsDependentOn("Clean") 30 | .Does(() => 31 | { 32 | NuGetRestore("./src/Reactive.EventAggregator.sln"); 33 | }); 34 | 35 | Task("Build") 36 | .IsDependentOn("Restore-NuGet-Packages") 37 | .Does(() => 38 | { 39 | MSBuild("./src/Reactive.EventAggregator.sln", settings => 40 | settings.SetConfiguration(configuration) 41 | .WithProperty("Version", version)); 42 | }); 43 | 44 | Task("Run-Unit-Tests") 45 | .IsDependentOn("Build") 46 | .Does(() => 47 | { 48 | XUnit2("./src/**/bin/" + configuration + "/*.Tests.dll"); 49 | }); 50 | 51 | 52 | Task("Package") 53 | .IsDependentOn("Run-Unit-Tests") 54 | .Does(() => 55 | { 56 | MSBuild("./src/Reactive.EventAggregator/Reactive.EventAggregator.csproj", settings => 57 | settings.SetConfiguration(configuration) 58 | .WithTarget("Pack") 59 | .WithProperty("Version", version)); 60 | }); 61 | 62 | 63 | ////////////////////////////////////////////////////////////////////// 64 | // TASK TARGETS 65 | ////////////////////////////////////////////////////////////////////// 66 | 67 | Task("Default") 68 | .IsDependentOn("Package"); 69 | 70 | ////////////////////////////////////////////////////////////////////// 71 | // EXECUTION 72 | ////////////////////////////////////////////////////////////////////// 73 | 74 | RunTarget(target); -------------------------------------------------------------------------------- /build.ps1: -------------------------------------------------------------------------------- 1 | ########################################################################## 2 | # This is the Cake bootstrapper script for PowerShell. 3 | # This file was downloaded from https://github.com/cake-build/resources 4 | # Feel free to change this file to fit your needs. 5 | ########################################################################## 6 | 7 | <# 8 | 9 | .SYNOPSIS 10 | This is a Powershell script to bootstrap a Cake build. 11 | 12 | .DESCRIPTION 13 | This Powershell script will download NuGet if missing, restore NuGet tools (including Cake) 14 | and execute your Cake build script with the parameters you provide. 15 | 16 | .PARAMETER Script 17 | The build script to execute. 18 | .PARAMETER Target 19 | The build script target to run. 20 | .PARAMETER Configuration 21 | The build configuration to use. 22 | .PARAMETER Verbosity 23 | Specifies the amount of information to be displayed. 24 | .PARAMETER Experimental 25 | Tells Cake to use the latest Roslyn release. 26 | .PARAMETER WhatIf 27 | Performs a dry run of the build script. 28 | No tasks will be executed. 29 | .PARAMETER Mono 30 | Tells Cake to use the Mono scripting engine. 31 | .PARAMETER SkipToolPackageRestore 32 | Skips restoring of packages. 33 | .PARAMETER ScriptArgs 34 | Remaining arguments are added here. 35 | 36 | .LINK 37 | http://cakebuild.net 38 | 39 | #> 40 | 41 | [CmdletBinding()] 42 | Param( 43 | [string]$Script = "build.cake", 44 | [string]$Target = "Default", 45 | [ValidateSet("Release", "Debug")] 46 | [string]$Configuration = "Release", 47 | [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")] 48 | [string]$Verbosity = "Verbose", 49 | [switch]$Experimental, 50 | [Alias("DryRun","Noop")] 51 | [switch]$WhatIf, 52 | [switch]$Mono, 53 | [switch]$SkipToolPackageRestore, 54 | [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] 55 | [string[]]$ScriptArgs 56 | ) 57 | 58 | [Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null 59 | function MD5HashFile([string] $filePath) 60 | { 61 | if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf)) 62 | { 63 | return $null 64 | } 65 | 66 | [System.IO.Stream] $file = $null; 67 | [System.Security.Cryptography.MD5] $md5 = $null; 68 | try 69 | { 70 | $md5 = [System.Security.Cryptography.MD5]::Create() 71 | $file = [System.IO.File]::OpenRead($filePath) 72 | return [System.BitConverter]::ToString($md5.ComputeHash($file)) 73 | } 74 | finally 75 | { 76 | if ($file -ne $null) 77 | { 78 | $file.Dispose() 79 | } 80 | } 81 | } 82 | 83 | Write-Host "Preparing to run build script..." 84 | 85 | if(!$PSScriptRoot){ 86 | $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent 87 | } 88 | 89 | $TOOLS_DIR = Join-Path $PSScriptRoot "tools" 90 | $NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe" 91 | $CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe" 92 | $NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" 93 | $PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config" 94 | $PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum" 95 | 96 | # Should we use mono? 97 | $UseMono = ""; 98 | if($Mono.IsPresent) { 99 | Write-Verbose -Message "Using the Mono based scripting engine." 100 | $UseMono = "-mono" 101 | } 102 | 103 | # Should we use the new Roslyn? 104 | $UseExperimental = ""; 105 | if($Experimental.IsPresent -and !($Mono.IsPresent)) { 106 | Write-Verbose -Message "Using experimental version of Roslyn." 107 | $UseExperimental = "-experimental" 108 | } 109 | 110 | # Is this a dry run? 111 | $UseDryRun = ""; 112 | if($WhatIf.IsPresent) { 113 | $UseDryRun = "-dryrun" 114 | } 115 | 116 | # Make sure tools folder exists 117 | if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) { 118 | Write-Verbose -Message "Creating tools directory..." 119 | New-Item -Path $TOOLS_DIR -Type directory | out-null 120 | } 121 | 122 | # Make sure that packages.config exist. 123 | if (!(Test-Path $PACKAGES_CONFIG)) { 124 | Write-Verbose -Message "Downloading packages.config..." 125 | try { (New-Object System.Net.WebClient).DownloadFile("http://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch { 126 | Throw "Could not download packages.config." 127 | } 128 | } 129 | 130 | # Try find NuGet.exe in path if not exists 131 | if (!(Test-Path $NUGET_EXE)) { 132 | Write-Verbose -Message "Trying to find nuget.exe in PATH..." 133 | $existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_) } 134 | $NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1 135 | if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) { 136 | Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)." 137 | $NUGET_EXE = $NUGET_EXE_IN_PATH.FullName 138 | } 139 | } 140 | 141 | # Try download NuGet.exe if not exists 142 | if (!(Test-Path $NUGET_EXE)) { 143 | Write-Verbose -Message "Downloading NuGet.exe..." 144 | try { 145 | (New-Object System.Net.WebClient).DownloadFile($NUGET_URL, $NUGET_EXE) 146 | } catch { 147 | Throw "Could not download NuGet.exe." 148 | } 149 | } 150 | 151 | # Save nuget.exe path to environment to be available to child processed 152 | $ENV:NUGET_EXE = $NUGET_EXE 153 | 154 | # Restore tools from NuGet? 155 | if(-Not $SkipToolPackageRestore.IsPresent) { 156 | Push-Location 157 | Set-Location $TOOLS_DIR 158 | 159 | # Check for changes in packages.config and remove installed tools if true. 160 | [string] $md5Hash = MD5HashFile($PACKAGES_CONFIG) 161 | if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or 162 | ($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) { 163 | Write-Verbose -Message "Missing or changed package.config hash..." 164 | Remove-Item * -Recurse -Exclude packages.config,nuget.exe 165 | } 166 | 167 | Write-Verbose -Message "Restoring tools from NuGet..." 168 | $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`"" 169 | 170 | if ($LASTEXITCODE -ne 0) { 171 | Throw "An error occured while restoring NuGet tools." 172 | } 173 | else 174 | { 175 | $md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII" 176 | } 177 | Write-Verbose -Message ($NuGetOutput | out-string) 178 | Pop-Location 179 | } 180 | 181 | # Make sure that Cake has been installed. 182 | if (!(Test-Path $CAKE_EXE)) { 183 | Throw "Could not find Cake.exe at $CAKE_EXE" 184 | } 185 | 186 | # Start Cake 187 | Write-Host "Running build script..." 188 | Invoke-Expression "& `"$CAKE_EXE`" `"$Script`" -target=`"$Target`" -configuration=`"$Configuration`" -verbosity=`"$Verbosity`" $UseMono $UseDryRun $UseExperimental $ScriptArgs" 189 | exit $LASTEXITCODE 190 | . $nuget restore .\src\Reactive.EventAggregator.sln 191 | 192 | # build the solution from scratch 193 | $version = "v4.0.30319" 194 | $sln = Join-Path (Get-ScriptDirectory) src\Reactive.EventAggregator.sln 195 | 196 | . $env:windir\Microsoft.NET\Framework\$version\MSBuild.exe $sln /t:Rebuild /p:Configuration=Release /m /v:q 197 | 198 | # package it up 199 | 200 | $nuspec = Join-Path (Get-ScriptDirectory) src\Reactive.EventAggregator\Reactive.EventAggregator.nuspec 201 | 202 | $nugetVersion = $env:APPVEYOR_BUILD_VERSION 203 | if ($nugetVersion -eq $null) 204 | { 205 | $nugetVersion = "4.0.0" 206 | } 207 | 208 | . $nuget pack $nuspec -Version $nugetVersion -------------------------------------------------------------------------------- /src/Reactive.EventAggregator.Tests/Reactive.EventAggregator.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net46 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Reactive.EventAggregator.Tests/SimpleTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reactive.Linq; 3 | using Xunit; 4 | using Shouldly; 5 | 6 | namespace Reactive.EventAggregator.Tests 7 | { 8 | public class SimpleTests 9 | { 10 | class SampleEvent { 11 | public int Status { get; set; } 12 | } 13 | 14 | [Fact] 15 | public void testing_subscribe() 16 | { 17 | // arrange 18 | var eventWasRaised = false; 19 | var eventPublisher = new EventAggregator(); 20 | 21 | // act 22 | eventPublisher.GetEvent() 23 | .Subscribe(se => eventWasRaised = true); 24 | 25 | eventPublisher.Publish(new SampleEvent()); 26 | 27 | // assert 28 | eventWasRaised.ShouldBe(true); 29 | } 30 | 31 | [Fact] 32 | public void testing_unsubscribe() 33 | { 34 | // arrange 35 | var eventWasRaised = false; 36 | var eventPublisher = new EventAggregator(); 37 | 38 | // act 39 | var subscription = eventPublisher.GetEvent() 40 | .Subscribe(se => eventWasRaised = true); 41 | 42 | subscription.Dispose(); 43 | eventPublisher.Publish(new SampleEvent()); 44 | 45 | // assert 46 | eventWasRaised.ShouldBe(false); 47 | } 48 | 49 | [Fact] 50 | public void testing_selective_subscribe() 51 | { 52 | // arrange 53 | var eventWasRaised = false; 54 | var eventPublisher = new EventAggregator(); 55 | 56 | // act 57 | eventPublisher.GetEvent() 58 | .Where(se => se.Status == 1) 59 | .Subscribe(se => eventWasRaised = true); 60 | 61 | eventPublisher.Publish(new SampleEvent { Status = 1 }); 62 | 63 | // assert 64 | eventWasRaised.ShouldBe(true); 65 | } 66 | 67 | [Fact] 68 | public void testing_selective_subscribe_ignored() 69 | { 70 | // arrange 71 | var eventWasRaised = false; 72 | var eventPublisher = new EventAggregator(); 73 | 74 | // act 75 | eventPublisher.GetEvent() 76 | .Where(se => se.Status != 1) 77 | .Subscribe(se => eventWasRaised = true); 78 | 79 | eventPublisher.Publish(new SampleEvent { Status = 1 }); 80 | 81 | // assert 82 | eventWasRaised.ShouldBe(false); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/Reactive.EventAggregator.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26228.4 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Reactive.EventAggregator.Tests", "Reactive.EventAggregator.Tests\Reactive.EventAggregator.Tests.csproj", "{07BF7AB0-9B7A-441E-BA11-067F574B35DA}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A944316B-3717-4182-9FCC-F4C513274CE9}" 9 | ProjectSection(SolutionItems) = preProject 10 | ..\appveyor.yml = ..\appveyor.yml 11 | ..\build.cake = ..\build.cake 12 | ..\CONTRIBUTING.md = ..\CONTRIBUTING.md 13 | ..\LICENSE.md = ..\LICENSE.md 14 | ..\README.md = ..\README.md 15 | EndProjectSection 16 | EndProject 17 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Reactive.EventAggregator", "Reactive.EventAggregator\Reactive.EventAggregator.csproj", "{CA3BF39A-923F-4ED0-8CFA-FE7C37788ACB}" 18 | EndProject 19 | Global 20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 21 | Debug|Any CPU = Debug|Any CPU 22 | Debug|ARM = Debug|ARM 23 | Debug|x86 = Debug|x86 24 | Release|Any CPU = Release|Any CPU 25 | Release|ARM = Release|ARM 26 | Release|x86 = Release|x86 27 | EndGlobalSection 28 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 29 | {07BF7AB0-9B7A-441E-BA11-067F574B35DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 30 | {07BF7AB0-9B7A-441E-BA11-067F574B35DA}.Debug|Any CPU.Build.0 = Debug|Any CPU 31 | {07BF7AB0-9B7A-441E-BA11-067F574B35DA}.Debug|ARM.ActiveCfg = Debug|Any CPU 32 | {07BF7AB0-9B7A-441E-BA11-067F574B35DA}.Debug|x86.ActiveCfg = Debug|Any CPU 33 | {07BF7AB0-9B7A-441E-BA11-067F574B35DA}.Release|Any CPU.ActiveCfg = Release|Any CPU 34 | {07BF7AB0-9B7A-441E-BA11-067F574B35DA}.Release|Any CPU.Build.0 = Release|Any CPU 35 | {07BF7AB0-9B7A-441E-BA11-067F574B35DA}.Release|ARM.ActiveCfg = Release|Any CPU 36 | {07BF7AB0-9B7A-441E-BA11-067F574B35DA}.Release|x86.ActiveCfg = Release|Any CPU 37 | {CA3BF39A-923F-4ED0-8CFA-FE7C37788ACB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 38 | {CA3BF39A-923F-4ED0-8CFA-FE7C37788ACB}.Debug|Any CPU.Build.0 = Debug|Any CPU 39 | {CA3BF39A-923F-4ED0-8CFA-FE7C37788ACB}.Debug|ARM.ActiveCfg = Debug|Any CPU 40 | {CA3BF39A-923F-4ED0-8CFA-FE7C37788ACB}.Debug|ARM.Build.0 = Debug|Any CPU 41 | {CA3BF39A-923F-4ED0-8CFA-FE7C37788ACB}.Debug|x86.ActiveCfg = Debug|Any CPU 42 | {CA3BF39A-923F-4ED0-8CFA-FE7C37788ACB}.Debug|x86.Build.0 = Debug|Any CPU 43 | {CA3BF39A-923F-4ED0-8CFA-FE7C37788ACB}.Release|Any CPU.ActiveCfg = Release|Any CPU 44 | {CA3BF39A-923F-4ED0-8CFA-FE7C37788ACB}.Release|Any CPU.Build.0 = Release|Any CPU 45 | {CA3BF39A-923F-4ED0-8CFA-FE7C37788ACB}.Release|ARM.ActiveCfg = Release|Any CPU 46 | {CA3BF39A-923F-4ED0-8CFA-FE7C37788ACB}.Release|ARM.Build.0 = Release|Any CPU 47 | {CA3BF39A-923F-4ED0-8CFA-FE7C37788ACB}.Release|x86.ActiveCfg = Release|Any CPU 48 | {CA3BF39A-923F-4ED0-8CFA-FE7C37788ACB}.Release|x86.Build.0 = Release|Any CPU 49 | EndGlobalSection 50 | GlobalSection(SolutionProperties) = preSolution 51 | HideSolutionNode = FALSE 52 | EndGlobalSection 53 | EndGlobal 54 | -------------------------------------------------------------------------------- /src/Reactive.EventAggregator.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 3 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 4 | <Policy><Descriptor Staticness="Static, Instance" AccessRightKinds="Public" Description="Test Methods"><ElementKinds><Kind Name="TEST_MEMBER" /></ElementKinds></Descriptor><Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /></Policy> 5 | <data /> 6 | <data><IncludeFilters /><ExcludeFilters /></data> -------------------------------------------------------------------------------- /src/Reactive.EventAggregator/EventAggregator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reactive.Linq; 3 | using System.Reactive.Subjects; 4 | 5 | namespace Reactive.EventAggregator 6 | { 7 | // based on http://joseoncode.com/2010/04/29/event-aggregator-with-reactive-extensions/ 8 | // and http://machadogj.com/2011/3/yet-another-event-aggregator-using-rx.html 9 | public class EventAggregator : IEventAggregator 10 | { 11 | readonly Subject subject = new Subject(); 12 | 13 | public IObservable GetEvent() 14 | { 15 | return subject.OfType().AsObservable(); 16 | } 17 | 18 | public void Publish(TEvent sampleEvent) 19 | { 20 | subject.OnNext(sampleEvent); 21 | } 22 | 23 | bool disposed; 24 | 25 | public void Dispose() 26 | { 27 | Dispose(true); 28 | } 29 | 30 | protected virtual void Dispose(bool disposing) 31 | { 32 | if (disposed) return; 33 | 34 | subject.Dispose(); 35 | 36 | disposed = true; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/Reactive.EventAggregator/IEventAggregator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Reactive.EventAggregator 4 | { 5 | public interface IEventAggregator : IDisposable 6 | { 7 | IObservable GetEvent(); 8 | void Publish(TEvent sampleEvent); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Reactive.EventAggregator/Reactive.EventAggregator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netstandard1.0;netstandard1.3;net45 4 | false 5 | José F. Romaniello, Brendan Forster 6 | 3.1.0 7 | http://opensource.org/licenses/mit 8 | https://github.com/shiftkey/Reactive.EventAggregator 9 | 2.12 10 | A portable EventAggregator based on Rx for .NET 4.5+ and .NET Standard 11 | true 12 | true 13 | true 14 | full 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | --------------------------------------------------------------------------------