jeudi 21 février 2019

Loose coupling for logging classes

I'm trying to make a class (actually 2) that will encapsulate some specific logging/telemetry technology. They are used in a decorator to log requests, like so:

var manager = new SpecificTelemetryManager();
....
public void PostRequest(string body) 
{
    var telem = manager.Start();
    controller.PostRequest();
    manager.Stop(telem);
}

I have this:

ITelemetryManager.cs

public interface ITelemetryManager
{
    ITelemetryOperation Start(string operationName);

    void Stop(ITelemetryOperation op);

}

ITelemetryOperation.cs

public interface ITelemetryOperation<T> : IDisposable
{

    T Operation { get; set; }

    void AddCustomProperties(IDictionary<string, string> customProperties);

}

SpecificTelemetryManager.cs (does not compile)

public class SpecificTelemetryHandler : ITelemetryManager
{

    private Client _client { get; set; }

    public SpecificTelemetryHandler()
    {
        _client = new Client();
    }

    public ITelemetryOperation Start(string name)
    {
        return new SpecificTelemetryOperation(_client.Start(name));
    }

    public void Stop(ITelemetryOperation op)
    {
        _client.StopOperation(op.Operation); // !!! THIS DOESNT KNOW THE TYPE
    }

}

SpecificTelemetryOperation.cs

public class SpecificTelemetryOperation : ITelemetryOperation<SomeMicrosoftClass>
{
    public SomeMicrosoftClass Operation { get; set; }

    public ApplicationInsightsTelemetryOperation(SomeMicrosoftClass op)
    {
        Operation = op;
    }

    public void AddCustomProperties(IDictionary<string, string> customProperties)
    {
        Operation.Props.AddRange(customProperties);
    }

    public void Dispose()
    {
        Operation.Dispose();
    }

}

Can anyone please provide some ideas on how to keep ITelemetryManager typeless (non generic) (so it won't be ITelemetryManager<Iwhatever>) and make sure that outside classes (the decorator) don't know what type of telemetry operations they are working on (Microsoft, AWS, Google, etc...). I want SpecificTelemetryManager and SpecificTelemetryOperation to have all the concrete classes that they would be referencing.

Design pattern for overcoming the reverse constructor order?

I have the following problem:

The base class expects to receive some data but the data is initialized by the derived class constructor which in C# is called after the base constructor was called.

Simplified example:

class Base
{
    string _s;

    protected Base(string s)
    {
        _s = s.ToLower();
    }
}

class Derived : Base
{
    public Derived(string path) : base(...)
    {
        // string can only be initialized at this point
    }
}

Question:

How can I run some code in derived class first, so I can pass the result to the base constructor ?

Implementation of construction + view pattern example

Was working through an example of a design pattern called Constructor + View by the author that was explained through types but was having trouble figuring out the implementation.

This is the module signature:

module User : {
  type t;
  type view = { name: string, age: int };
  let make: (~name:string, ~age:int) => option(t);
  let view: t => view;
};

So User.t is hidden but from one function you can pattern match the user record

At first was thinking User.t and User.view could have the same fields:

module User: {
  type t;
  type view = { name: string, age: int, };
  let make: (~name: string, ~age: int) => option(t);
  let view: t => view;
} = {
  type t = { name: string, age: int, };
  type view = { name: string, age: int, };
  let make = (~name, ~age) => Some({name, age});
  let view = t => {name: t.name, age: t.age};
};

But got an error that looks like it can't tell the difference between view and t:

  Values do not match:
    let make: (~name: string, ~age: int) => option(view)
  is not included in
    let make: (~name: string, ~age: int) => option(t)

Tried a couple more things, the first just taking out make and trying to get the view function to work but same issue:

module User: {
  type t;
  type view = { name: string, age: int, };
  let view: t => view;
} = {
  type t = { name: string, age: int, };
  type view = { name: string, age: int, };
  let view = t => {name: t.name, age: t.age};
};

with error:

  Values do not match:
    let view: view => view
  is not included in
    let view: t => view

The second try was for having the view type be a subset of the fields (which was the use case I was hoping to use this pattern) but this has the same error as above:

module User: {
  type t;
  type view = { name: string, age: int, };
  let view: t => view;
} = {
  type t = { name: string, age: int, email: string };
  type view = { name: string, age: int, };
  let view = t => {name: t.name, age: t.age};
};

My question here is if there's a way to implement something to fit the first module signature with User.view being the same fields or subset of fields as User.t? Can make it work if the records have different fields or if I separate the records by modules but curious about that specific use case.

the best way to get an action result

I'm curious if getting an action result is a valid approach, and if it is then how to do that?

For example let's say I have a page with form for creating entities, after successful entity creation I'd like to redirect user to entity's detail view, otherwise (on failure) update the form by error messages. I'd like to perform that without mixing up application layers (eg. to not redirect user in epic/effect after success).

I have a few approaches to this problem in mind:

  1. dispatch a "trigger" action (entity_add), then dispatch a success (entity_add_success) or failure (entity_add_failure) action somewhere in my epic/effect, wait for failure or success action and do an action - this approach has a noticable drawback: other entities may be created meanwhile and how to distinguish the failure/success actions of entities in that case?

  2. dispatch a trigger action with additional callback parameter which should be called when action result becomes determined, this approach has a drawback as well (not as big as the previous one though): possibility of creating callback hell.

  3. give up at using flux in that case, use services directly, design drawback: mixing application layers

I'd be glad to hear any ideas.

Where to transform Redux state for use in UI

I have a list of "Events":

{
 id: 1,
 description: "Did something",
 date: <date>, 
 eventTypeId: 1
}

I fetch these Events in componentDidUpdate and then they are passed to my component as a prop form redux connect mapStateToProps - they come from a "selector" - getEvents.

I want to display them on react-big-calendar which wants them in this format -

Event {
  title: string,
  start: Date,
  end: Date,
  allDay?: boolean
  resource?: any,
}

Where do I transform them from my object to the react-big-calendar object?

It seems like this must occur in the component, so if I switch to another calendar libary, my redux code would remain unchanged.

Is there a standard pattern for doing this? Should I just do this directly in my render method?

render() {
 let bigCalEvents = this.props.events.map(e => <big cal event>);
 ....
}

Or is there a better way to do this?

Looking for a Design Pattern or Library

Is there a specific design pattern I could use to generate a string expression with some nested conditions?

Given:

Builder.red().and().blue().or(white().and().black()).toString()

Result should be:

red and blue or ( white and black )

Initially I started using the builder pattern (maybe it's not the appropriate one) but I got stuck when I had to generate the nested condition. Ideally the usage should be like in the above snippet (method chaining).

I need that for a java project (version 8) and the generated expression will be used as spring expression language (couldn't find a spring utility class that does that).

How do i make a tree data structure that can hold two differnet generic types for parent and children

I am ashamed to admit that I am sitting on this problem for many many hours. But I just want to implement it the way I have it structured in the diagramm below....

I want to model the world with continents/countrys/states and citys in it. Each model has a reference to its parent and a list of references to its children except the world only has children (because there cant be a parent to it) and the city only has a parent-reference because it doesnt go deeper. (I want to implement it that for example "World" does not have a parent field, likewise "city" does not have a List < Children > field.

I was about to implement it in a tree data structure like following (I left out the implementations): Only interfaces shown for simplicity

To give you an idea of the code of the interfaces I included the bare minimum of it here:

public interface IRoot<TChild>
{
    List<TChild> Children { get; set; }
    void AddChild(TChild child);
}
public interface ILeaf<TParent>
{
    TParent Parent { get; set; }
}
public interface INode<TParent, TChild> : IRoot<TChild>, ILeaf<TParent> { }

And a little code of the implementation:

public class Root<TChild> : IRoot<TChild>
{
    public List<TChild> Children { get; set; }
    public void AddChild(TChild child) { //... }
}
public class Leaf<TParent> : ILeaf<TParent>
{
    public TParent Parent { get; set; }
}
public class Node<TParent, TChild> : INode<TParent, TChild>
{
    private IRoot<TChild> root;
    private ILeaf<TParent> leaf;

    //...
}

Lastly the code of the classes I want to structure:

public class World : Root<Continent> { }
public class Continent : Node<World, Country> { }
public class Country : Node<Continent, State> { }
public class State : Node<Country, City> { }
public class City : Leaf<City> { }

Here comes the Problem:

Now to Add a child object in Root.AddChild(TChild) I need to access < TChlid >.Parent so I would need to constraint the generic TChild to "ILeaf< IRoot < TChild >>" like this:

public class Root<TChild> : IRoot<TChild> where TChild : ILeaf<Root<TChild>>
{
    public void AddChild(TChild child)
    {
        child.Parent = this;
    }
}

But doing this, I get the Error

CS0311 C# The type cannot be used as type parameter in the generic type or method. There is no implicit reference conversion from to.

At this line

public class World : Root<Continent> { }

If anyone can help me figure the problem out and find a solution I would sooo appreciate it