Lets say you have simple chained method but you are trying to access or set a value in a class property (internal/external doesnt matter). Using a Func seems to be working and finds the relation between generic class that is passed and access its properties correctly but i am not sure if its necessary.
Is there a way of setting the method variable cleanly as in Main method below since it is aware of the Generic class association without doing new Props().Property for example?
//sample console app
public class Props {
public string FirstProp = "lets say object";
public string SecondProp = "Pretend some other object";
}
public class Logic<T> where T : class, new()
{
private string outString { get; set; }
public Logic<T> GetPropertyValue(Func<T, object> propertySelector)
{
return this;
}
public Logic<T> GetLambda(Expression<Func<T, object>> propertySelector)
{
var breakpointCheck = propertySelector; //{x => x.SecondProp}
return this;
}
}
class Program
{
static void Main(string[] args)
{
var Test =
new Logic<Props>()
.GetPropertyValue(x => x.FirstProp) //dummy check
.GetLambda(x => x.SecondProp); //passed correctly {x => x.SecondProp}
var HowToGetThis =
new Logic<Props>()
.GetPropertyValue(FirstProp) // or GetPropertyValue(Props.FirstProp)
.GetLambda(x => x.SecondProp);
}
}
Question
How do I define an incoming Type T constraint that will allow me to call a static method on the class (of type T) to get the intended IndexModel object for passing to Mongo?
Background
I'm currently trying to write a Mongo Provider class that will allow me to ensure my particular database and collection are present before doing any operations with them, since there is a potential that the container or server it resides in could be destroyed and recreated at any time, and I'd prefer to have a safe way in code to ensure that the external dependency is there (instance is beyond my control, so I have to trust that something is there).
One of the things I'm trying to do, since I've managed to do what I stated above for Database and Collection instantiation, is to also generate indexes. My idea was to have a static method on the classes that would return their specific definition of an index model. This way, each class would be responsible for their own Mongo indexes, rather than some convoluted switch-case statement in my Provider based on the incoming type of T.
My first idea was to have an interface that shared this method, but Interfaces don't allow you to declare a static method. Similarly, I tried an Abstract Base-class and found that the static implementation would call the base class that defined the method, rather than any overrides in an inheritor.
Sample Code
public class MyClass
{
public DateTime DateValue { get; set; }
public int GroupId { get; set; }
public string DataType { get; set; }
public static IEnumerable<CreateIndexModel<MyClass>> GetIndexModel(IndexKeysDefinitionBuilder<MyClass> builder)
{
yield return new CreateIndexModel<MyClass>(
builder.Combine(
builder.Descending(entry => entry.DateValue),
builder.Ascending(entry => entry.GroupId),
builder.Ascending(entry => entry.DataType)
)
);
}
}
Edit
I guess I should probably include a shell of my Mongo Provider class. See below:
Edit #2 due to questions about how this hasn't solved my problem, I'm updating the MongoProvider to have the problematic code. Note: Once this method is included, the class will no longer compile, since it isn't possible given what I've done thus far.
public class MongoProvider
{
private readonly IMongoClient _client;
private MongoPrivder(ILookup<string, string> lookup, IMongoClient client)
{
_client = client;
foreach(var database in lookup)
foreach(var collection in database)
Initialize(database.Key, collection);
}
public MongoProvider(IConfiguration config) :this(config.GetMongoObjects(), config.GetMongoClient())
{}
public MongoProvider(IConfiguration config, IMongoClient client) : this(config.GetMongoObjects(), client)
{}
private void Initialize(string database, string collection)
{
var db = _client.GetDatabase(database);
if (!db.ListCollectionNames().ToList().Any(name => name.Equals(collection)))
db.CreateCollection(collection);
}
// The Problem
private void InitializeIndex<T>(string database, string collection)
{
IEnumerable<CreateIndexModel<T>> models;
switch (T)
{
case MyClass:
model = MyClass.GetIndexModel();
break;
default:
break;
}
await _client.GetDatabase(database)
.GetCollection<T>(collection)
.Indexes
.CreateManyAsync(models);
}
}
Edit #3
As a stop-gap, I've gone ahead and done something terrible (not sure if it's going to work yet), and I'll supply the example so you can know my best solution thus far.
public static class Extensions
{
#region Object Methods
public static T TryCallMethod<T>(this object obj, string methodName, params object[] args) where T : class
{
var method = obj.GetType().GetMethod(methodName);
if (method != null)
{
return method.Invoke(obj, args) as T;
}
return default;
}
#endregion
}
This allows me to do the following (inside of MongoProvider)
private async void InitializeIndex<T>(string database, string collection) where T : new()
{
var models = new T().TryCallMethod<IEnumerable<CreateIndexModel<T>>>("GetIndexModel");
await _client.GetDatabase(database)
.GetCollection<T>(collection)
.Indexes
.CreateManyAsync(models);
}
Since it doesn't look like I'm going to get an answer to this, I figured I would provide my solution for future searches of this question. Basically, I added an extension method to the base object class, and used reflection to determine if the method I was looking for was there. From there, I returned a value of true or false, depending on if the method was found, and output the return value to a parameter, in the traditional TryGet pattern.
Note to Future Readers
I do not recommend this approach. This is just how I solved my problem for accessing a method on a type of T. Ideally, an instance method would be implemented, and a signature defined in a common Interface, but that wasn't going to work for my use case.
My Answer
public static class Extensions
{
#region Object Methods
public static bool TryCallMethod<T>(this object obj, string methodName, out T result, params object[] args) where T : class
{
result = null;
var method = obj.GetType().GetMethod(methodName);
if (method == null)
return false;
result = method.Invoke(obj, args) as T;
return true;
}
#endregion
}
My data class looks like this (obfuscated from actual usage)
[BsonDiscriminator("data")]
public class DataClass
{
#region Private Fields
private const string MongoCollectionName = "Data";
#endregion
#region Public Properties
public string CollectionName => MongoCollectionName;
[BsonId]
public ObjectId Id { get; set; }
[BsonElement("date_value")]
public DateTime DateValue { get; set; }
[BsonElement("group_id")]
public int GroupId { get; set; }
[BsonElement("data_type")]
public string DataType { get; set; }
[BsonElement("summary_count")]
public long SummaryCount { get; set; }
[BsonElement("flagged_count")]
public long FlaggedCount { get; set; }
[BsonElement("error_count")]
public long ErrorCount { get; set; }
#endregion
#region Constructor
public DataClass()
{
}
public DataClass(int groupId, string dataType = null, long summaryCount = 0, long flaggedCount = 0, long errorCount = 0)
{
Id = ObjectId.GenerateNewId();
DateValue = DateTime.UtcNow;
GroupId = groupId;
DocCount = summaryCount;
DataType = dataType ?? "default_name";
FlaggedCount = flaggedCount;
ErrorCount = errorCount;
}
#endregion
#region Public Methods
public static IEnumerable<CreateIndexModel<AuditEntry>> GetIndexModel(IndexKeysDefinitionBuilder<AuditEntry> builder)
{
yield return new CreateIndexModel<AuditEntry>(
builder.Combine(
builder.Descending(entry => entry.DateValue),
builder.Ascending(entry => entry.GroupId),
builder.Ascending(entry => entry.DataType)
)
);
}
#endregion
}
I would then call the method in the following fashion, inside my MongoProvider class. The ellipses are present to identify that more code exists within the class.
public class MongoProvider : IMongoProvider
{
#region Private Fields
private readonly IMongoClient _client;
#endregion
#region Constructor
...
#endregion
#region Private Methods
private void Initialize(string database, string collection)
{
var db = _client.GetDatabase(database);
if (!db.ListCollectionNames().ToList().Any(name => name.Equals(collection)))
db.CreateCollection(collection);
}
private async Task InitializeIndex<T>(string database, string collection) where T : new()
{
if(new T().TryCallMethod<IEnumerable<CreateIndexModel<T>>>("GetIndexModel", out var models, new IndexKeysDefinitionBuilder<T>()))
await _client.GetDatabase(database)
.GetCollection<T>(collection)
.Indexes
.CreateManyAsync(models);
}
private static void ValidateOptions<T>(ref FindOptions<T, T> options)
{
if(options != null)
return;
options = new FindOptions<T, T>
{
AllowPartialResults = null,
BatchSize = null,
Collation = null,
Comment = "AspNetWebService",
CursorType = CursorType.NonTailable,
MaxAwaitTime = TimeSpan.FromSeconds(10),
MaxTime = TimeSpan.FromSeconds(10),
Modifiers = null,
NoCursorTimeout = false,
OplogReplay = null
};
}
private static FilterDefinition<T> GetFilterDefinition<T>(Func<FilterDefinitionBuilder<T>, FilterDefinition<T>>[] builders)
{
if(builders.Length == 0)
builders = new Func<FilterDefinitionBuilder<T>, FilterDefinition<T>>[] {b => b.Empty};
return new FilterDefinitionBuilder<T>()
.And(builders
.Select(b => b(new FilterDefinitionBuilder<T>()))
);
}
#endregion
#region Public Methods
public async Task<IReadOnlyCollection<T>> SelectManyAsync<T>(string database, string collection, FindOptions<T, T> options = null, params Func<FilterDefinitionBuilder<T>, FilterDefinition<T>>[] builders) where T : new()
{
ValidateOptions(ref options);
await InitializeIndex<T>(database, collection);
var filter = GetFilterDefinition(builders);
var find = await _client.GetDatabase(database)
.GetCollection<T>(collection)
.FindAsync(filter, options);
return await find.ToListAsync();
}
...
#endregion
}
Very new to C# so forgive me if this is a silly question.
If I have a base class called Validator, and a number of classes which inherit from this class such as validateFirstname, validateSecondname etc... is it possible to write a method which will loop through each of these subclasses and instantiate each?
Something along the lines of
public class loadValidators
{
public loadValidators()
{
foreach (subclass in class)
{
// instantiate class here
}
}
}
Any help is much appreciated as always.
Try this:
var validator_type = typeof (Validator);
var sub_validator_types =
validator_type
.Assembly
.DefinedTypes
.Where(x => validator_type.IsAssignableFrom(x) && x != validator_type)
.ToList();
foreach (var sub_validator_type in sub_validator_types)
{
Validator sub_validator = (Validator)Activator.CreateInstance(sub_validator_type);
}
This code assumes that all the sub classes live in the same assembly/project as the Validator class.
Also, it assumes that each of the subclasses have a public parameterless constructor.
Please note that I would not recommend this approach.
Instead you should do something like this to solve your problem (of modeling/using multiple validators):
public interface IValidator
{
bool Validate(SomeObject something);
}
public class FirstNameValidator : IValidator
{
public bool Validate(SomeObject something)
{
...
}
}
public class LastNameValidator : IValidator
{
public bool Validate(SomeObject something)
{
...
}
}
public class CompositeValidator : IValidator
{
private readonly IValidator[] m_Validators;
public CompositeValidator(params IValidator[] validators)
{
m_Validators = validators;
}
public bool Validate(SomeObject something)
{
foreach (IValidator validator in m_Validators)
{
if (!validator.Validate(something))
return false;
}
return true;
}
}
The CompositeValidator wraps multiple validators and knows how to validate objects using those validators.
You can use it like this:
var composite_validator = new CompositeValidator(new FirstNameValidator() , new LastNameValidator());
composite_validator.Validate(obj);
I have an object that only initializes itself with barebones data when constructed (fast), and loads itself for real (slow) when first accessed. The idea is that I'm creating a lot of these barebones objects at startup and hash them into a map, then fully load each object whenever it is individually accessed for the first time. The problem is that I cannot guarantee how clients will interact with this object, there are multiple public methods that might be invoked.
Is there a good pattern to support this kind of situation? The obvious (and my current) solution is to track state with an internal bool, check against that bool in every function that might be invoked, and load that way. But that requires code duplication of that behavior across all public functions, and is vulnerable to errors.
I can imagine a single point-of-entry method that then dishes out behaviors based on a client request type etc., but before I go consider going down that road I want to see if there's a commonly accepted approach/pattern that I might not be aware of. I'm doing this in C#, but any insight is appreciated.
If I understood what you want to achieve, you are looking for the Proxy Design Pattern, more specifically, a virtual Proxy.
Refer to http://www.dofactory.com/net/proxy-design-pattern
A small example would be something like:
public abstract class IObjectProvider
{
public abstract IObjectProvider Object{get;}
public abstract void doStuff();
}
public class RealObject : IObjectProvider
{
public RealObject()
{
//Do very complicated and time taking stuff;
}
public override IObjectProvider Object
{
get { return this; }
}
public override void doStuff()
{
//do this stuff that these objects normally do
}
}
public class ObjectProxy : IObjectProvider
{
private IObjectProvider objectInstance = null;
public override IObjectProvider Object
{
get
{
if (objectInstance == null)
objectInstance = new RealObject();
return objectInstance;
}
}
public override void doStuff()
{
if(objectInstance!=null)
objectInstance.doStuff();
}
}
public class SkeletonClass
{
public IObjectProvider Proxy1 = new ObjectProxy();
public IObjectProvider Proxy2 = new ObjectProxy();
}
static void Main(String[] args)
{
//Objects Not Loaded
SkeletonClass skeleton = new SkeletonClass();
//Proxy1 loads object1 on demand
skeleton.Proxy1.Object.doStuff();
//Proxy2 not loaded object2 until someone needs it
}
Here's an example of dynamic proxy approach.
using System;
using System.Diagnostics;
using Castle.DynamicProxy; //Remember to include a reference, too. It's nugettable package is Castle.Core
namespace ConsoleApp
{
public class ActualClass
{
//Have static instances of two below for performance
private static ProxyGenerator pg = new ProxyGenerator();
private static ActualClassInterceptor interceptor = new ActualClassInterceptor();
//This is how we get ActualClass items that are wrapped in the Dynamic Proxy
public static ActualClass getActualClassInstance()
{
ActualClass instance = new ActualClass();
return pg.CreateClassProxyWithTarget<ActualClass>(instance, interceptor);
}
//Tracking whether init has been called
private bool initialized = false;
//Will be used as evidence of true initialization, i.e. no longer null
private int? someValue = null;
public void Initialize()
{
if (!initialized)
{
//do some initialization here.
someValue = -1; //Will only get set to non-null if we've run this line.
initialized = true;
}
}
//Any methods you want to intercept need to be virtual!
public virtual int replaceValue(int value)
{
//below will blow up, if someValue has not been set to -1 via Initialize();
int oldValue = someValue.Value;
someValue = value;
return oldValue;
}
//block off constructor from public to enforce use of getActualClassInstance
protected ActualClass() { }
}
public class ActualClassInterceptor : ActualClass, IInterceptor
{
public void Intercept(IInvocation invocation)
{
//Call initialize before proceeding to call the intercepted method
//Worth noting that this is the only place we actually call Initialize()
((ActualClass)invocation.InvocationTarget).Initialize();
invocation.Proceed();
}
}
class Program
{
static void Main(string[] args)
{
ActualClass instance1 = ActualClass.getActualClassInstance();
ActualClass instance2 = ActualClass.getActualClassInstance();
int x1 = instance1.replaceValue(41);
int x2 = instance2.replaceValue(42);
int y1 = instance1.replaceValue(82);
Debug.Assert(y1 == 41);
int y2 = instance2.replaceValue(84);
Debug.Assert(y2 == 42);
var read = Console.ReadKey();
}
}
}
I'm trying to run some initialization code before a test. I've tried the suggestions in other questions, but it doesn't seem to work. My domain model raises events via the following class:
public static class DomainEvents
{
private static readonly object #lock = new object();
private static Action<IDomainEvent> raiseEvent;
public static void Raise<TEvent>(TEvent #event) where TEvent : class, IDomainEvent
{
// omitted for brevity
}
public static void RegisterEventPublisher(Action<IDomainEvent> eventPublisher)
{
lock (#lock)
{
raiseEvent = eventPublisher;
}
}
}
For testing purposes I would like to capture these events in a static list. What is the best way of doing this?
Update
The problem was caused by the order in which the tests are run (which as Alexander points out below, is not guaranteed). In one of my specs I had registered a mock event publisher. The fact that the spec would often run in different orders meant that a) to begin with I didn't know I had the issue (the "problem" spec always ran last) and b) Once I started having the issue, the number of failing tests would often vary between runs (making it even more confusing).
The lesson learned - clean up any static resources after each context has run. You can do this by implementing ICleanupAfterEveryContextInAssembly.
Maybe I'm misunderstanding the issue, but the basic pattern is:
public class WhenSomeDomainEventIsRaised
{
private IList<IDomainEvent> EventsRaised = new List<IDomainEvent>();
Establish context = () =>
{
// subscribe to events; when raised, add to EventsRaised list
}
}
If you want to do this for all tests or a subset of tests:
public abstract class DomainSpecification
{
protected IList<IDomainEvent> EventsRaised = new List<IDomainEvent>();
Establish context = () =>
{
// subscribe to events; when raised, add to EventsRaised list
}
}
You can have all specs that need this behaviour inherit from this class, and MSpec will take care of running all Establish blocks along the inheritance hierarchy.
This works for me:
using System;
using System.Collections.Generic;
using Machine.Specifications;
namespace AssemblyContextSpecs
{
public static class DomainEvents
{
static readonly object #lock = new object();
static Action<IDomainEvent> raiseEvent;
public static void Raise<TEvent>(TEvent #event) where TEvent : class, IDomainEvent
{
raiseEvent(#event);
}
public static void RegisterEventPublisher(Action<IDomainEvent> eventPublisher)
{
lock (#lock)
{
raiseEvent = eventPublisher;
}
}
}
public interface IDomainEvent
{
}
class FooEvent : IDomainEvent
{
}
public class DomainEventsContext : IAssemblyContext
{
internal static IList<IDomainEvent> Events = new List<IDomainEvent>();
public void OnAssemblyStart()
{
DomainEvents.RegisterEventPublisher(x => Events.Add(x));
}
public void OnAssemblyComplete()
{
}
}
public class When_a_domain_event_is_raised
{
Because of = () => DomainEvents.Raise(new FooEvent());
It should_capture_the_event =
() => DomainEventsContext.Events.ShouldContain(x => x.GetType() == typeof(FooEvent));
}
}
Shouldn't RegisterEventPublisher rather be RegisterEventSubscriber?