Comments (11)
Hi.
Did you find a solution?
from specflow.assist.dynamic.
No
from specflow.assist.dynamic.
I found code to build nested table for class but dont know how to change it to build dynamic table without setting T
using System;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using TechTalk.SpecFlow;
using TechTalk.SpecFlow.Assist;
public static class TableExtensions
{
public static T BuildInstance<T>(this Table table)
{
T result = table.CreateInstance<T>();
// find sub-properties by looking for "."
var propNames = table.Rows.OfType<TableRow>()
.Where(x => x[0].Contains("."))
.Select(x => Regex.Replace(x[0], @"^(.+?)\..+$", "$1"));
foreach (var propName in propNames)
{
// look for matching property in result object
var prop = typeof(T).GetProperty(
propName,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
if (prop != null)
{
// create sub-table with relevant rows (field == propName.something)
var subTable = new Table("field", "value");
var re = new Regex(string.Format(@"^{0}\.([^\.]*)$", propName), RegexOptions.IgnoreCase);
table.Rows.OfType<TableRow>().Where(x => re.IsMatch(x[0]))
.Select(x => new[] { re.Replace(x[0], "$1"), x[1] })
.ToList()
.ForEach(x => subTable.AddRow(x));
// make recursive call to create child object
var createInstance = typeof(TableExtensions)
.GetMethod(
"BuildInstance",
BindingFlags.Public | BindingFlags.Static,
null,
CallingConventions.Any,
new Type[] { typeof(Table) },
null);
createInstance = createInstance.MakeGenericMethod(prop.PropertyType);
object propValue = createInstance.Invoke(null, new object[] { subTable });
// assign child object to result
prop.SetValue(result, propValue);
}
}
return result;
}
}
from specflow.assist.dynamic.
Hi,
yeah... that is not something I forsaw the tool doing. So it's not implemented.
But I'm thinking that you can do this, pretty easy, using step argument transformations, like I have done here https://github.com/marcusoftnet/SpecFlow.Assist.Dynamic/blob/master/SpecFlow.Assist.Dynamic/DynamicStepArgumentTransformations.cs
Instead of my code you can plug-in the code that you have above.
[Binding]
public class Haxy89ArgumentTransformations
{
[StepArgumentTransformation]
public dynamic TransformToEnumerable(Table table)
{
// your code from above
}
}
You might want to remove the <StepArgumentTransformation>
node from you config file
<stepAssemblies>
<stepAssembly assembly="SpecFlow.Assist.Dynamic" />
</stepAssemblies>
that SpecFlowAssistDynamic is adding when installing.
from specflow.assist.dynamic.
Yeah but still, I want to build object dynamicaly without provide class as T.
In my simple code I have to provide some class as T
from specflow.assist.dynamic.
Ok - but why do you need to do that?
If you change your signature to
[StepArgumentTransformation]
public dynamic BuildInstance(Table table) {}
You don't need a at all.
Read up on https://specflow.org/documentation/Step-Argument-Transformations/ for ways to ensure that you only get called for the steps that required transformation. As written above the code will get called for every step with a table.
from specflow.assist.dynamic.
This is not going to work with dynamic:
public static dynamic BuildInstance(this Table table)
{
dynamic result = table.CreateInstance<dynamic>();
// find sub-properties by looking for "."
var propNames = table.Rows.OfType<TableRow>()
.Where(x => x[0].Contains("."))
.Select(x => Regex.Replace(x[0], @"^(.+?)\..+$", "$1"));
foreach (var propName in propNames)
{
// look for matching property in result object
var prop = typeof(T).GetProperty(
propName,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
if (prop != null)
{
// create sub-table with relevant rows (field == propName.something)
var subTable = new Table("field", "value");
var re = new Regex(string.Format(@"^{0}\.([^\.]*)$", propName), RegexOptions.IgnoreCase);
table.Rows.OfType<TableRow>().Where(x => re.IsMatch(x[0]))
.Select(x => new[] { re.Replace(x[0], "$1"), x[1] })
.ToList()
.ForEach(x => subTable.AddRow(x));
// make recursive call to create child object
var createInstance = typeof(TableExtensions)
.GetMethod(
"BuildInstance",
BindingFlags.Public | BindingFlags.Static,
null,
CallingConventions.Any,
new Type[] { typeof(Table) },
null);
createInstance = createInstance.MakeGenericMethod(prop.PropertyType);
object propValue = createInstance.Invoke(null, new object[] { subTable });
// assign child object to result
prop.SetValue(result, propValue);
}
}
return result;
from specflow.assist.dynamic.
But you don't need to make it an extension method (using static
and this
). You can use the [StepArgumentTransformation] way instead.
Or did I miss something in your original question? You want an extension method?
Then it's outside the scope of this tool, I'm afraid.
from specflow.assist.dynamic.
It is not necessary for me to make it extension method but marking it as StepARgumentTransformation is not the solutions. I still have to provied T class, but I dont want to. I want to buld dynamic object with nested dynamic objects
from specflow.assist.dynamic.
Hmmm - this is something we would need to pair on I'm afraid.
Pretty sure it could work with a StepArgumentTransformation, but I might be wrong.
I'll see if I can play around with it later.
Sorry to stop here and I hope you can find a way.
Thanks for using my little tool
from specflow.assist.dynamic.
Thanks
from specflow.assist.dynamic.
Related Issues (16)
- Change to hintpath HOT 6
- Handling reserved characters in property names HOT 7
- Convert solution to Visual Studio 2015
- Leading zero removed is this a bug HOT 11
- references mismatch HOT 2
- Indicate data type of values which are different in DynamicSetComparisonException.Differences
- CreateDynamicInstance from a table with a single Field and Value doesn't create the ExpandoObject as expected
- Ability to specify property name casing rules, or a way to match property names HOT 2
- `Property value type conversions` section in wiki needs to be updated with the correct order of operations
- Support .NET Core, .NET Standard #20 HOT 4
- Latest specflow versions are not supported
- table value is converting to date time by default HOT 1
- Forcing a particular datatype to be created HOT 6
- Add support for additional types, specified by user. HOT 13
- double.NaN is not equal to double.NaN
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from specflow.assist.dynamic.