Generic build adding fields - macros

Consider this code:
http://try.haxe.org/#5AD6e
class Test
{
public static function main()
{
var foo = new FluentFoo(null, { bar: 1 }).hello();
}
}
class Foo
{
public function new(options:{ bar:Int }) {}
public function hello()
{
trace("Hi there");
}
}
class Fluent
{
private var parent:Null<Fluent>;
public function new(parent:Null<Fluent>)
{
this.parent = parent;
}
public function end()
{
if(parent != null) {
return parent;
}
throw 'Top level already reached';
}
}
class FluentFoo extends Fluent
{
public var base:Foo;
public function new(parent:Null<Fluent>, options:{ bar:Int })
{
super(parent);
base = new Foo(options);
}
public function hello()
{
base.hello();
return this;
}
}
I want to generate classes such as FluentFoo automatically.
In pseudohaxe code:
import haxe.Constraints.Constructible;
class Test
{
public static function main()
{
var foo = new Fluent<Foo>(null, { bar: 1 }).hello();
}
}
class Foo
{
public function new(options:{ bar:Int }) {}
public function hello()
{
trace("Hi there");
}
}
#:generic
#:genericBuild(FluentMacro.build())
class Fluent<T:Constructible<Dynamic -> Void>>
{
private var parent:Null<Fluent>;
private var base:T;
public function new(parent:Null<Fluent>, options:Dynamic)
{
this.parent = parent;
this.base = new T(options);
}
public function end()
{
if(parent != null) {
return parent;
}
throw 'Top level already reached';
}
}
class FluentMacro
{
public static function build()
{
//Get "T" public methods
//Add them to class calling this genericBuild method (in this example to Fluent_Foo)
//Modify them so they return "this"
}
}
I know that I can't use #:build as all I'd get from Context.getLocalType would be TInst(Fluent,[TInst(Fluent.T,[])]).
However, I'm not completely understanding haxe manual on generic builds - they are under the same section "Type building macros" as normal #:build, yet the build method is expected to return ComplexType, and not an array of fields. Is it possible at all to add fields in #:genericBuild?
Thank you

That was a bit more complex than I anticipated, but I did it. For other people to use: https://github.com/Misiur/Fluent

Related

Why am I getting "OneTimeSetUp: No suitable constructor was found..."?

I am using NUnit3 and trying to make use of TestFixtureSource in the following class hierarchy:
public class AtataTestFixtureData
{
public static IEnumerable FixtureParams
{
get
{
yield return new TestFixtureData(new AtataConfigContainer
{
AtataJsonConfig = new BaseAtataConfig()
});
}
}
}
[TestFixtureSource(typeof(AtataConfigContainer), nameof(AtataTestFixtureData.FixtureParams))]
public class AtataTestsWithDbBase : OzCsTestsWithDbBase, IAtataAbpTests
{
public AtataTestsWithDbBase()
{
}
public AtataTestsWithDbBase(AtataConfigContainer aAtataConfigContainer)
{
AtataAbpTestsAdapter = AtataAbpTestsAdapter.Instance;
AtataConfigContainer = aAtataConfigContainer;
}
}
public class SomeSiteComAuTestsBase : AtataTestsWithDbBase
{
public SomeSiteComAuTestsBase(AtataConfigContainer aAtataConfigContainer) : base(aAtataConfigContainer)
{
}
}
[TestFixture]
public class IndexTests : SomeSiteComAuTestsBase
{
/// <summary>
/// Class constructor.
/// </summary>
public IndexTests(AtataConfigContainer aAtataConfigContainer) : base(aAtataConfigContainer)
{
}
[Test]
public void Get()
{
//Arrange
//Act
IndexPageObject indexPage = Go.To<IndexPageObject>();
//Assert
}
}
When I run IndexTests.Get() I get the exception OneTimeSetUp: No suitable constructor was found but according to public IndexTests(AtataConfigContainer aAtataConfigContainer) : base(aAtataConfigContainer) I have the needed constructor.
What am I missing here?
You are getting this error because your IndexTests class has a constructor that takes parameters, but your TestFixtureSource is on a base class. The TestFixtureSource needs to be on your IndexTests. The TestFixtureSource attribute is not inherited.

How do I setup a list of test organizations with my new DBContext?

I have an application with uses multiple contexts for EF, some are code first, some server first, and all are dynamic.
I have a class that I call to get these contexts in my app.
Each context implements an interface such as:
public interface IDatabaseContextSwitcher
{
IVGSContext GetDatabase(string organization);
IVGSContext GetDatabase(Guid organizationGuid, string email);
IVGSServerConn GetServerDatabase(string databaseName);
IAuthContext GetAuthorizationDatabase();
}
I therefore has a class that implments the instances of these interfaces in the application. (VGSContext, VGSServerConn, and AuthContext).
I am trying to test these in my test project. I have made new classes from the interfaces with the plan to plug in some DbSets into these new classes and then test that my controllers do the correct thing.
However, I can't seem to figure out how to initialize the DBSets.
For example the following dies on Add:
public AuthContextForTesting()
{
Organizations.Add(new Organization()
{OrganizationName = "Test1", PK_Organization = Guid.Parse("34CE4F83-B3C9-421B-B1F3-42BBCDA9A004")});
var cnt = Organizations.Count();
}
public DbSet<Organization> Organizations { get; set; }
I tried to initialize the DBSet with:
Organizations=new DbSet();
But it gives an error that this is not allowed due to permissions.
How do I set up my initial dbsets in code for my tests?
To be able to do this, you first have to derive a class from DBSet. Sadly, my app uses both Core EF and EF 6 so I had to create 2 classes.
EF 6 Class
public class FakeDbSet<T> : System.Data.Entity.DbSet<T>, IDbSet<T> where T : class
{
List<T> _data;
public FakeDbSet()
{
_data = new List<T>();
}
public override T Find(params object[] keyValues)
{
throw new NotImplementedException("Derive from FakeDbSet<T> and override Find");
}
public override T Add(T item)
{
_data.Add(item);
return item;
}
public override T Remove(T item)
{
_data.Remove(item);
return item;
}
public override T Attach(T item)
{
return null;
}
public T Detach(T item)
{
_data.Remove(item);
return item;
}
public override T Create()
{
return Activator.CreateInstance<T>();
}
public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, T
{
return Activator.CreateInstance<TDerivedEntity>();
}
public List<T> Local
{
get { return _data; }
}
public override IEnumerable<T> AddRange(IEnumerable<T> entities)
{
_data.AddRange(entities);
return _data;
}
public override IEnumerable<T> RemoveRange(IEnumerable<T> entities)
{
for (int i = entities.Count() - 1; i >= 0; i--)
{
T entity = entities.ElementAt(i);
if (_data.Contains(entity))
{
Remove(entity);
}
}
return this;
}
Type IQueryable.ElementType
{
get { return _data.AsQueryable().ElementType; }
}
System.Linq.Expressions.Expression IQueryable.Expression
{
get { return _data.AsQueryable().Expression; }
}
IQueryProvider IQueryable.Provider
{
get { return _data.AsQueryable().Provider; }
}
IEnumerator IEnumerable.GetEnumerator()
{
return _data.GetEnumerator();
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return _data.GetEnumerator();
}
}
The EF Core had to include some interfaces to work.
public class FakeCoreDbSet<T> : Microsoft.EntityFrameworkCore.DbSet<T> , IQueryable, IEnumerable<T> where T : class
{
List<T> _data;
public FakeCoreDbSet()
{
_data = new List<T>();
}
public override T Find(params object[] keyValues)
{
throw new NotImplementedException("Derive from FakeDbSet<T> and override Find");
}
public override EntityEntry<T> Add(T item)
{
_data.Add(item);
//return item;
return null;
}
public override EntityEntry<T> Remove(T item)
{
_data.Remove(item);
//return item;
return null;
}
public override EntityEntry<T> Attach(T item)
{
return null;
}
public T Detach(T item)
{
_data.Remove(item);
return item;
}
public IList GetList()
{
return _data.ToList();
}
//public override T Create()
//{
// return Activator.CreateInstance<T>();
//}
public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, T
{
return Activator.CreateInstance<TDerivedEntity>();
}
public List<T> Local
{
get { return _data; }
}
public override void AddRange(IEnumerable<T> entities)
{
_data.AddRange(entities);
//return _data;
}
public override void RemoveRange(IEnumerable<T> entities)
{
for (int i = entities.Count() - 1; i >= 0; i--)
{
T entity = entities.ElementAt(i);
if (_data.Contains(entity))
{
Remove(entity);
}
}
// this;
}
Type IQueryable.ElementType
{
get { return _data.AsQueryable().ElementType; }
}
System.Linq.Expressions.Expression IQueryable.Expression
{
get { return _data.AsQueryable().Expression; }
}
IQueryProvider IQueryable.Provider
{
get { return _data.AsQueryable().Provider; }
}
IEnumerator IEnumerable.GetEnumerator()
{
return _data.GetEnumerator();
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return _data.GetEnumerator();
}
}
Once these were created I could use MockObjects to get to them.
Note _dbContextSwitcher is the class created with a Moq that calls the different databases.
var vgsdatabase = new Mock<IVGSContext>();
var settings=new FakeCoreDbSet<Setting>();
settings.Add(new Setting()
{
SettingID = "OrgPrivacy",
PK_Setting = Guid.NewGuid(),
UserID = "",
Value = "No"
});
vgsdatabase.Setup(s => s.Setting).Returns(settings);
_dbcontextSwitcher.Setup(s => s.GetDatabase(It.IsAny<string>())).Returns(vgsdatabase.Object);

Access members of inner class from the outer class - TypeScript

I'm trying to group some members of a class in TypeScript. Consider the following class:
export class MyClass {
private member: string = 'foo';
public getFoo(): string {
this._doSomething();
return this.member;
}
// Helper
_doSomething() { console.log(this.member); }
}
What I basically want to do is to wrap _doSomething with a namespace (let's call the namespace helpers) so inside getFoo() I can call this.helpers._doSomething().
Of course, this is super easy to do in Javascript since we can define an object as a member and define the helper functions inside the object.
In TypeScript, I almost got the same effect through class expressions:
export class MyClass {
private member: string = 'foo';
public getFoo(): string {
this.helpers._doSomething();
return this.member;
}
private helpers = class {
// To have access to the parent's members
constructor(private parent: MyClass) { }
public _doSomething() { console.log(this.parent.member); }
};
}
The only problem is that the MyClass can't have access to helpers class members.
How do I get access to the inner class members from the outer class?
Is there a better way to achieve the namespace helpers?
Any help would be appreciated.
Updated
Using the accepted answer achieves the goal:
export class MyClass {
private member: string = 'foo';
public getFoo(): string {
this.helpers._doSomething();
return this.member;
}
private helpers = new (class {
// To have access to the parent's members
constructor(private parent: MyClass) { }
public _doSomething() { console.log(this.parent.member); }
})(this);
}
You just defined the class, to have access to the non-static members you have to new it up. You can do this inline like so :
export class MyClass {
private member: string = 'foo';
public getFoo(): string {
this.helpers._doSomething();
return this.member;
}
private helpers = new (class {
// To have access to the parent's members
constructor(private parent: MyClass) { }
public _doSomething() { console.log(this.parent.member); }
})(this);
}
Or if you want to have multiple instances of the helper class you can new it up as needed:
public getFoo(): string {
let h = new this.helpers(this);
let h1 = new this.helpers(this);
h._doSomething();
h1._doSomething();
return this.member;
}
You can achieve a similar effect by using the merging of a class and a namespace, the problem is you will not have access to private members, while your solution requires this:
export class MyClass {
// Must be public for access from helper
public member: string = 'foo';
public getFoo(): string {
let h = new MyClass.helpers(this);
h._doSomething();
return this.member;
}
}
export namespace MyClass {
// must be exported to be accesible from the class
export class helpers {
// To have access to the parent's members
constructor(private parent: MyClass) { }
public _doSomething() { console.log(this.parent.member); }
}
}

MvvmCross binding property of custom type to custom view

I tried bind property of custom type in View Model with custom View, but in Binder method "SetValue(object value)" value is always null. Why it happens? Is it impossible bind property of custom type with custom view in MvvmCross?
My ViewModel:
public class RecipesFiltersVM : MvxViewModel
{
public SearchField DishField { get; private set; }
public SearchField CuisineField { get; private set; }
public SearchField IngredientField { get; private set; }
private readonly IFiltersService _filtersService;
public RecipesFiltersVM(IFiltersService filtersService)
{
_filtersService = filtersService;
UpdateSearchFields ();
}
private async void UpdateSearchFields ()
{
var allFilters = await _filtersService.LoadAllFilters ();
DishField = new SearchField (
allFilters
.Where(f => f.Type == FilterType.Dish)
.ToList()
);
CuisineField = new SearchField (
allFilters
.Where(f => f.Type == FilterType.Cuisine)
.ToList()
);
IngredientField = new SearchField (
allFilters
.Where(f => f.Type == FilterType.Ingredient)
.ToList()
);
}
}
My SearchField:
public class SearchField : MvxViewModel
{
private String _searchResult;
public String SearchResult {
get { return _searchResult; }
set {
_searchResult = value;
RaisePropertyChanged (() => SearchResult);
UpdateFoundFilters ();
}
}
private ObservableCollection<Filter> _foundFilters;
public ObservableCollection<Filter> FoundFilters {
get { return _foundFilters; }
set {
_foundFilters = value;
RaisePropertyChanged (() => FoundFilters);
}
}
}
In CustomView:
public class SearchFieldView : UIView
{
public UITextField SearchResult { get { return _searchResult; } }
private UITextField _searchResult;
public UITableView FoundFilters { get { return _foundFilters; } }
private UITableView _foundFilters;
}
In Binder:
public class SearchFieldViewWithSearchFieldBinder : MvxTargetBinding
{
protected SearchFieldView SearchFieldView {
get { return (SearchFieldView)Target; }
}
public SearchFieldViewWithSearchFieldBinder (SearchFieldView target)
: base (target)
{
}
public override void SetValue (object value)
{
//value is always null!
}
public override Type TargetType {
get
{
return typeof(SearchField);
}
}
public override MvxBindingMode DefaultMode {
get
{
return MvxBindingMode.TwoWay;
}
}
}
Setup:
protected override void FillTargetFactories (Cirrious.MvvmCross.Binding.Bindings.Target.Construction.IMvxTargetBindingFactoryRegistry registry)
{
registry.RegisterCustomBindingFactory<SearchFieldView> (
"SearchField",
indicators => new SearchFieldViewWithSearchFieldBinder(indicators)
);
base.FillTargetFactories (registry);
}
In ViewController:
var set = this.CreateBindingSet<RecipesFiltersDialog, RecipesFiltersVM>();
set.Bind (_dish).For("SearchField").To (vm => vm.DishField);
set.Bind (_cuisine).For("SearchField").To (vm => vm.CuisineField);
set.Bind (_ingredient).For("SearchField").To (vm => vm.IngredientField);
set.Apply ();
UPD
Solved with two ways update ViewModel code. First I changed custom property declaration like:
private SearchField _dishField;
public SearchField DishField {
get
{
return _dishField;
}
set
{
_dishField = value;
RaisePropertyChanged (() => DishField);
}
}
Second I initialize my properties in ViewModel constructor before UpdateSearchFields () execution:
public RecipesFiltersVM(IFiltersService filtersService)
{
_filtersService = filtersService;
DishField = new SearchField (new List<Filter> ());
CuisineField = new SearchField (new List<Filter> ());
IngredientField = new SearchField (new List<Filter> ());
UpdateSearchFields ();
}
You need to create your own custom bindings for your custom view. For instance if you have followed the normal MvvmCross practice of using public C# properties and C# events to define the items in your custom view then you should be able to do something like this:
public class SearchFieldView : UIView, IMvxBindable
{
public IMvxBindingContext BindingContext { get; set; }
public SearchFieldView()
{
this.CreateBindingContext();
}
public UITextField SearchResult { get { return _searchResult; } }
private UITextField _searchResult;
public UITableView FoundFilters { get { return _foundFilters; } }
private UITableView _foundFilters;
[MvxSetToNullAfterBinding]
public object DataContext
{
get { return BindingContext.DataContext; }
set { BindingContext.DataContext = value; }
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
BindingContext.ClearAllBindings();
}
base.Dispose(disposing);
}
}
And then it should just "work." For inspiration checkout things like MvxView or MvxTableViewCell.
Alternatively you may be able to do your own MvxPropertyInfoTargetBinding like how MvvmCross is handling the UISegmentedControlBindings by implementing something like MvxUISegmentedControlSelectedSegmentTargetBinding.
Solved with Stuart's comment in two ways update ViewModel code. First I changed custom property declaration like:
private SearchField _dishField;
public SearchField DishField {
get
{
return _dishField;
}
set
{
_dishField = value;
RaisePropertyChanged (() => DishField);
}
}
Second I initialize my properties in ViewModel constructor before UpdateSearchFields () execution:
public RecipesFiltersVM(IFiltersService filtersService)
{
_filtersService = filtersService;
DishField = new SearchField (new List<Filter> ());
CuisineField = new SearchField (new List<Filter> ());
IngredientField = new SearchField (new List<Filter> ());
UpdateSearchFields ();
}

resolve all given the Type

From the Autofac documentation I can see how to get all registrations for a class T:
public T[] ResolveAll<T>()
{
return _container.Resolve<IEnumerable<T>>().ToArray();
}
But when I only have the Type available, how can I get the equivalent results?
public Array ResolveAll(Type service)
{
return _container.Resolve( ???
}
I am trying to implement a wrapper class which has a pre-defined interface.
EDIT
For quick reference, the answer from Matthew Watson (with relevant ideas from David L) is:
public Array ResolveAll(Type service)
{
var typeToResolve = typeof(IEnumerable<>).MakeGenericType(service);
return _container.Resolve(typeToResolve) as Array;
}
Here is an example. I've added asserts to prove that the types returned from ResolveAll<T>(this IContainer self) are the same (and in the same order) as those returned from ResolveAll(this IContainer self, Type type):
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Autofac;
using Autofac.Core;
namespace AutofacTrial
{
public abstract class Base
{
public abstract string Name { get; }
public override string ToString()
{
return Name;
}
}
public sealed class Derived1: Base
{
public override string Name
{
get
{
return "Derived1";
}
}
}
public sealed class Derived2: Base
{
public override string Name
{
get
{
return "Derived2";
}
}
}
public sealed class Derived3: Base
{
public override string Name
{
get
{
return "Derived3";
}
}
}
static class Program
{
static void Main()
{
var builder = new ContainerBuilder();
builder.RegisterType<Derived1>().As<Base>();
builder.RegisterType<Derived2>().As<Base>();
builder.RegisterType<Derived3>().As<Base>();
var container = builder.Build();
var array1 = container.ResolveAll(typeof(Base));
var array2 = container.ResolveAll<Base>();
Trace.Assert(array1.Length == 3);
Trace.Assert(array2.Length == 3);
for (int i = 0; i < array1.Length; ++i)
{
Trace.Assert(array1[i].GetType() == array2[i].GetType());
Console.WriteLine(array1[i]);
}
}
public static T[] ResolveAll<T>(this IContainer self)
{
return self.Resolve<IEnumerable<T>>().ToArray();
}
public static object[] ResolveAll(this IContainer self, Type type)
{
Type enumerableOfType = typeof(IEnumerable<>).MakeGenericType(type);
return (object[]) self.ResolveService(new TypedService(enumerableOfType));
}
}
}
The underling implementation is the same
I also used Reflector to look at the implementation of Resolve<IEnumerable<T>>(), and it winds up doing this:
public static TService Resolve<TService>(this IComponentContext context, IEnumerable<Parameter> parameters)
{
return (TService) context.Resolve(typeof(TService), parameters);
}
which calls:
public static object Resolve(this IComponentContext context, Type serviceType, IEnumerable<Parameter> parameters)
{
return context.ResolveService(new TypedService(serviceType), parameters);
}
So the two must be equivalent, since they are implemented that way.
You can invoke _container.Resolve by calling your wrapped method via reflection (MSDN), but in doing so you will lose your compile-time type safety.
public class Container
{
public T[] ResolveAll<T>()
{
return _container.Resolve<IEnumerable<T>>().ToArray();
}
public object ResolveAllGeneric(Type t)
{
MethodInfo method = GetType().GetMethod("ResolveAll")
.MakeGenericMethod(new Type[] { t });
return method.Invoke(this, new object[] { });
}
}