Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Override of default mapping between event and handler now possible #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,36 @@ public class NewCustomerEventHandler : IEventGridHandler {
}
}
```
## Custom mapping
To use a custom mapping, create your own implementation of ShartEventGridMapper.
The following mapper, will map based on a convention that the eventhandler must start with {eventsubject}_

```cs
public class SubjectConventionMapper : EventGridMapper
{
private readonly Dictionary<string, List<Type>> handlers = new Dictionary<string, List<Type>>();

public override void AddMapping(string eventType, Type type)
{
if (handlers.Any(h => h.Key == eventType.ToLower()))
handlers[eventType].Add(type);
else
handlers.Add(eventType.ToLower(), new List<Type> { type });
}

public override Type LookUpMapping(Event item)
{
var key = item.EventType.ToLower();
if (handlers.ContainsKey(key) && handlers[key].Any(t => t.Name.StartsWith(item.Subject + "_")))
return handlers[key].First(t => t.Name.StartsWith(item.Subject + "_"));
return null;
}
}
```

To use the new mapper, add it to the EventGridOptions

```cs
opt.Mapper=new SubjectConventionMapper();
```

8 changes: 7 additions & 1 deletion SharpEventGridServer.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26923.0
VisualStudioVersion = 15.0.27130.2010
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpEventGridServer", "SharpEventGridServer\SharpEventGridServer.csproj", "{AE0D64BC-F59D-42F4-8533-F7724F1410BB}"
EndProject
Expand All @@ -12,6 +12,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{46039ACF-7
README.md = README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpMappingOverrideSample", "SharpMappingOverrideSample\SharpMappingOverrideSample.csproj", "{553B96A6-9C1B-4182-8BA4-5590BCD59860}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -26,6 +28,10 @@ Global
{97BC76E8-A746-4F28-BC38-701648ED78EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{97BC76E8-A746-4F28-BC38-701648ED78EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{97BC76E8-A746-4F28-BC38-701648ED78EC}.Release|Any CPU.Build.0 = Release|Any CPU
{553B96A6-9C1B-4182-8BA4-5590BCD59860}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{553B96A6-9C1B-4182-8BA4-5590BCD59860}.Debug|Any CPU.Build.0 = Debug|Any CPU
{553B96A6-9C1B-4182-8BA4-5590BCD59860}.Release|Any CPU.ActiveCfg = Release|Any CPU
{553B96A6-9C1B-4182-8BA4-5590BCD59860}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
23 changes: 23 additions & 0 deletions SharpEventGridServer/EventGridMapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SharpEventGrid;

namespace SharpEventGridServer
{
public class EventGridMapper
{
private readonly Dictionary<string, Type> handlers = new Dictionary<string, Type>();

public virtual void AddMapping(string eventType, Type type)
{
handlers.Add(eventType.ToLower(), type);
}

public virtual Type LookUpMapping(Event item)
{
var resulttype = handlers.FirstOrDefault(i => i.Key == item.EventType.ToLower());
return resulttype.Equals(default(KeyValuePair<string, Type>)) ? null : resulttype.Value;
}
}
}
32 changes: 19 additions & 13 deletions SharpEventGridServer/EventGridOptions.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
using SharpEventGrid;

namespace SharpEventGridServer {
public class EventGridOptions {
private Type _defaultMapping;
private Dictionary<string, Type> _handlers = new Dictionary<string, Type>();
namespace SharpEventGridServer
{
public class EventGridOptions
{
protected Type _defaultMapping;

internal IServiceProvider ServiceProvider { get; set; }

public string EventsPath { get; set; } = "api/events";
Expand All @@ -14,22 +15,27 @@ public class EventGridOptions {
public string ValidationKey { get; set; }
public string ValidationValue { get; set; }
public Action<string, bool, string> AutoValidateSubscriptionAttemptNotifier { get; set; }

public void MapEvent<T>(string eventType) where T : IEventGridHandler {
_handlers.Add(eventType.ToLower(), typeof(T));
public EventGridMapper Mapper = new EventGridMapper();
public virtual void MapEvent<T>(string eventType) where T : IEventGridHandler
{
Mapper.AddMapping(eventType, typeof(T));
}
public void MapDefault<T>() where T : IEventGridHandler {
public void MapDefault<T>() where T : IEventGridHandler
{
_defaultMapping = typeof(T);
}

public void SetValidationKey(string key, string value) {
public void SetValidationKey(string key, string value)
{
ValidationKey = key;
ValidationValue = value;
}

internal IEventGridHandler ResolveHandler(Event item) {
var key = item.EventType.ToLower();
Type typeToCreate = _handlers.ContainsKey(key) ? _handlers[key] : _defaultMapping;
internal virtual IEventGridHandler ResolveHandler(Event item)
{
var typeToCreate = Mapper.LookUpMapping(item);
if (typeToCreate == null)
typeToCreate = _defaultMapping;
var handler = ServiceProvider.GetService(typeToCreate) ?? Activator.CreateInstance(typeToCreate);
return (IEventGridHandler)handler;
}
Expand Down
1 change: 1 addition & 0 deletions SharpEventGridServer/SharpEventGridServer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.0.1" />
<PackageReference Include="Microsoft.Extensions.Options" Version="2.0.0" />
<PackageReference Include="SharpEventGrid" Version="1.1.0" />
</ItemGroup>
Expand Down
44 changes: 44 additions & 0 deletions SharpMappingOverrideSample/Controllers/SendEventsController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using SharpEventGrid;

namespace SharpMappingOverrideSample {
public class SendEventsController : Controller {
private readonly HttpClient _client;

public SendEventsController(HttpClient client) {
_client = client;
}

[HttpGet("api/test/subscription")]
public async Task<IActionResult> TestSubscription() {
var response = await SendEvent(EventTypes.SubscriptionValidationEvent, new ValidationEvent { ValidationCode = "foo" });
return Ok(response);
}

[HttpGet("api/test/event")]
public async Task<IActionResult> TestEvent(string eventType, string message) {
var response = await SendEvent(eventType, message);
return Ok(response);
}
private async Task<string> SendEvent(string eventType, object data) {
var url = $"{Request.Scheme}://{Request.Host.Value}/api/events?{Request.QueryString}";
var item = new Event {
EventType = eventType,
Subject = "mySubject",
Data = data
};
var json = JsonConvert.SerializeObject(new List<Event> { item });
var response = await _client.PostAsync(url, new StringContent(json));
var body = await response.Content.ReadAsStringAsync();
if (String.IsNullOrEmpty(body)) {
body = "OK";
}
return body;
}
}
}
12 changes: 12 additions & 0 deletions SharpMappingOverrideSample/EventHandlers/DefaultMappingHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Diagnostics;
using System.Threading.Tasks;
using SharpEventGrid;
using SharpEventGridServer;

namespace SharpMappingOverrideSample {
public class DefaultMappingHandler : IEventGridHandler {
public async Task ProcessEvent(Event eventItem) {
Debug.WriteLine($"{nameof(DefaultMappingHandler)} {eventItem.EventType}");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Diagnostics;
using System.Threading.Tasks;
using SharpEventGrid;
using SharpEventGridServer;

namespace SharpMappingOverrideSample {
public class mySubject_NewCustomerEventHandler : IEventGridHandler {

private IDatabase _database;
public mySubject_NewCustomerEventHandler(IDatabase database) {
_database = database;
}

public async Task ProcessEvent(Event eventItem) {
var newCustomerEvent = eventItem.DeserializeEvent<NewCustomerEvent>();
await _database.SaveAsync(newCustomerEvent);
Debug.WriteLine($"{nameof(mySubject_NewCustomerEventHandler)} {eventItem.EventType}");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Diagnostics;
using System.Threading.Tasks;
using SharpEventGrid;
using SharpEventGridServer;

namespace SharpMappingOverrideSample {
public class mySubject_SomeEventHandler : IEventGridHandler {
public async Task ProcessEvent(Event eventItem) {
Debug.WriteLine($"{nameof(mySubject_SomeEventHandler)} {eventItem.EventType}");
}
}
}
5 changes: 5 additions & 0 deletions SharpMappingOverrideSample/NewCustomerEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace SharpMappingOverrideSample {
public class NewCustomerEvent {

}
}
18 changes: 18 additions & 0 deletions SharpMappingOverrideSample/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;

namespace SharpMappingOverrideSample
{
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
}
29 changes: 29 additions & 0 deletions SharpMappingOverrideSample/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:29119/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"SharpEventGridServerSample": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:29120/"
}
}
}
9 changes: 9 additions & 0 deletions SharpMappingOverrideSample/Services/Database.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Threading.Tasks;

namespace SharpMappingOverrideSample {
public class Database : IDatabase {
public async Task SaveAsync(object item) {
//example
}
}
}
7 changes: 7 additions & 0 deletions SharpMappingOverrideSample/Services/IDatabase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using System.Threading.Tasks;

namespace SharpMappingOverrideSample {
public interface IDatabase {
Task SaveAsync(object item);
}
}
23 changes: 23 additions & 0 deletions SharpMappingOverrideSample/SharpMappingOverrideSample.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
</ItemGroup>

<ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\SharpEventGridServer\SharpEventGridServer.csproj" />
</ItemGroup>

</Project>
43 changes: 43 additions & 0 deletions SharpMappingOverrideSample/Startup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System.Diagnostics;
using System.Net.Http;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using SharpEventGridServer;

namespace SharpMappingOverrideSample {
public class Startup {
public Startup(IConfiguration configuration) {
Configuration = configuration;
}

public IConfiguration Configuration { get; }

public void ConfigureServices(IServiceCollection services) {
services.AddSingleton(new HttpClient());
services.AddSingleton(new mySubject_SomeEventHandler());
services.AddSingleton<IDatabase, Database>();
services.AddMvc();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
}
var opt = new EventGridOptions();
opt.AutoValidateSubscription = true;
opt.AutoValidateSubscriptionAttemptNotifier = (url, success, message) => {
Debug.WriteLine($"Validation attempt: {url} -> Success: {success}: {message}");
};
opt.EventsPath = "api/events";
opt.MapEvent<mySubject_SomeEventHandler>("someEventType");
opt.MapEvent<mySubject_NewCustomerEventHandler>("newCustomerEventType");
opt.MapDefault<DefaultMappingHandler>();
opt.SetValidationKey("key", "foo");
app.UseEventGrid(opt);
opt.Mapper=new SubjectConventionMapper();
app.UseMvc();
}
}
}
Loading