-
Notifications
You must be signed in to change notification settings - Fork 2k
/
FaultInjectionTransactionStateAttribute.cs
73 lines (65 loc) · 3.33 KB
/
FaultInjectionTransactionStateAttribute.cs
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
72
73
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Orleans.Runtime;
using Orleans.Transactions.Abstractions;
namespace Orleans.Transactions.TestKit
{
public interface IFaultInjectionTransactionalStateConfiguration : ITransactionalStateConfiguration
{
}
[AttributeUsage(AttributeTargets.Parameter)]
public class FaultInjectionTransactionalStateAttribute : Attribute, IFacetMetadata, IFaultInjectionTransactionalStateConfiguration
{
public string StateName { get; }
public string StorageName { get; }
public FaultInjectionTransactionalStateAttribute(string stateName, string storageName = null)
{
this.StateName = stateName;
this.StorageName = storageName;
}
}
public interface IFaultInjectionTransactionalStateFactory
{
IFaultInjectionTransactionalState<TState> Create<TState>(IFaultInjectionTransactionalStateConfiguration config) where TState : class, new();
}
public class FaultInjectionTransactionalStateFactory : IFaultInjectionTransactionalStateFactory
{
private IGrainActivationContext context;
public FaultInjectionTransactionalStateFactory(IGrainActivationContext context)
{
this.context = context;
}
public IFaultInjectionTransactionalState<TState> Create<TState>(IFaultInjectionTransactionalStateConfiguration config) where TState : class, new()
{
TransactionalState<TState> transactionalState = ActivatorUtilities.CreateInstance<TransactionalState<TState>>(this.context.ActivationServices, new TransactionalStateConfiguration(config), this.context);
FaultInjectionTransactionalState<TState> deactivationTransactionalState = ActivatorUtilities.CreateInstance<FaultInjectionTransactionalState<TState>>(this.context.ActivationServices, transactionalState, this.context);
deactivationTransactionalState.Participate(context.ObservableLifecycle);
return deactivationTransactionalState;
}
}
public class FaultInjectionTransactionalStateAttributeMapper : IAttributeToFactoryMapper<FaultInjectionTransactionalStateAttribute>
{
private static readonly MethodInfo create =
typeof(IFaultInjectionTransactionalStateFactory).GetMethod("Create");
public Factory<IGrainActivationContext, object> GetFactory(ParameterInfo parameter, FaultInjectionTransactionalStateAttribute attribute)
{
IFaultInjectionTransactionalStateConfiguration config = attribute;
// use generic type args to define collection type.
MethodInfo genericCreate = create.MakeGenericMethod(parameter.ParameterType.GetGenericArguments());
object[] args = new object[] { config };
return context => Create(context, genericCreate, args);
}
private object Create(IGrainActivationContext context, MethodInfo genericCreate, object[] args)
{
IFaultInjectionTransactionalStateFactory factory = context.ActivationServices.GetRequiredService<IFaultInjectionTransactionalStateFactory>();
return genericCreate.Invoke(factory, args);
}
}
}