GoogleCloudVision c# - how to unit test the service - c#

I've implemented a Google Cloud Vision service in my backend code. I want to unit test the service but I don't know how to mock it.
Here's my current code that I'm going to mock. Is there a way to inject the ImageAnnotatorClient so I could mock it?
public class GoogleCloudVisionService : IGoogleCloudVision
{
private readonly GoogleCloudVisionSettings googleCloudVisionSettings;
private ImageAnnotatorClient client;
public GoogleCloudVisionService(IOptions<GoogleCloudVisionSettings> googleCloudVisionSettings)
{
this.googleCloudVisionSettings = googleCloudVisionSettings.Value.WithParsedKey();
var credential = GoogleCredential.FromJson(this.googleCloudVisionSettings.ApiJson);
ImageAnnotatorClientBuilder clientBuilder = new ImageAnnotatorClientBuilder();
clientBuilder.Credential = credential;
client = clientBuilder.Build();
}
public async Task<SafeSearchAnnotation> GetImageAnnotation(byte[] imageBytes)
{
var image = Image.FromBytes(imageBytes);
var annotation = await client.DetectSafeSearchAsync(image);
return annotation;
}
public async Task<bool> IsImageSafe(byte[] imageBytes)
{
var annotations = await GetImageAnnotation(imageBytes);
var isSafe = annotations.Adult < googleCloudVisionSettings.Annotations.Adult &&
annotations.Racy < googleCloudVisionSettings.Annotations.Racy &&
annotations.Violence < googleCloudVisionSettings.Annotations.Violence &&
annotations.Medical < googleCloudVisionSettings.Annotations.Medical &&
annotations.Spoof < googleCloudVisionSettings.Annotations.Spoof;
return isSafe;
}
}

Finally got a working code after looking some examples in our codebase
public class GoogleCloudVisionServiceUnitTests
{
private Infrastructure.GoogleCloud.Api api;
public GoogleCloudVisionServiceUnitTests()
{
var faker = new Faker<Infrastructure.GoogleCloud.Api>()
.RuleFor(x => x.Type, f => f.Random.String2(6))
.RuleFor(x => x.ProjectId, f => f.Random.String2(6))
.RuleFor(x => x.PrivateKeyId, f => f.Random.String2(6))
.RuleFor(x => x.PrivateKey, f => f.Random.String2(6))
.RuleFor(x => x.ClientEmail, f => f.Random.String2(6))
.RuleFor(x => x.ClientId, f => f.Random.String2(6))
.RuleFor(x => x.AuthUri, f => f.Random.String2(6))
.RuleFor(x => x.TokenUri, f => f.Random.String2(6))
.RuleFor(x => x.AuthProviderUrl, f => f.Random.String2(6))
.RuleFor(x => x.ClientCertUrl, f => f.Random.String2(6));
api = faker.Generate(1).First();
}
[Fact]
public async Task GivenSafeImage_ShouldReturnAnnotations()
{
// Arrange
var faker = new Faker();
var expectedAnnotation = new SafeSearchAnnotation
{
Adult = Likelihood.Likely,
Racy = Likelihood.Likely,
Medical = Likelihood.Likely,
Spoof = Likelihood.Likely,
Violence = Likelihood.Likely
};
var mockOptions = new Mock<ImageAnnotatorClient>();
mockOptions.Setup(mock => mock.DetectSafeSearchAsync(It.IsAny<Image>(), It.IsAny<ImageContext>(), It.IsAny<CallSettings>()))
.ReturnsAsync(expectedAnnotation);
var json = JsonConvert.SerializeObject(api);
byte[] bytes = Encoding.Default.GetBytes(json);
var googleCloudVisionSettings = new GoogleCloudVisionSettings
{
Key = Convert.ToBase64String(bytes),
Annotations = new Annotations
{
Adult = Likelihood.Likely,
Racy = Likelihood.Likely,
Medical = Likelihood.Likely,
Spoof = Likelihood.Likely,
Violence = Likelihood.Likely
}
};
// Act
var googleCloudVisionService = new GoogleCloudVisionService(mockOptions.Object, Options.Create(googleCloudVisionSettings));
var annotations = await googleCloudVisionService.GetImageAnnotation(faker.Random.Bytes(512));
// Assert
annotations.Adult.Should().Be(googleCloudVisionSettings.Annotations.Adult);
annotations.Racy.Should().Be(googleCloudVisionSettings.Annotations.Racy);
annotations.Medical.Should().Be(googleCloudVisionSettings.Annotations.Medical);
annotations.Spoof.Should().Be(googleCloudVisionSettings.Annotations.Spoof);
annotations.Violence.Should().Be(googleCloudVisionSettings.Annotations.Violence);
}
[Fact]
public async Task GivenSafeImage_ShouldReturnTrue()
{
// Arrange
var faker = new Faker();
var expectedAnnotation = new SafeSearchAnnotation
{
Adult = Likelihood.VeryUnlikely,
Racy = Likelihood.VeryUnlikely,
Medical = Likelihood.VeryUnlikely,
Spoof = Likelihood.VeryUnlikely,
Violence = Likelihood.VeryUnlikely
};
var mockOptions = new Mock<ImageAnnotatorClient>();
mockOptions.Setup(mock => mock.DetectSafeSearchAsync(It.IsAny<Image>(), It.IsAny<ImageContext>(), It.IsAny<CallSettings>()))
.ReturnsAsync(expectedAnnotation);
var json = JsonConvert.SerializeObject(api);
byte[] bytes = Encoding.Default.GetBytes(json);
var googleCloudVisionSettings = new GoogleCloudVisionSettings
{
Key = Convert.ToBase64String(bytes),
Annotations = new Annotations
{
Adult = Likelihood.Likely,
Racy = Likelihood.Likely,
Medical = Likelihood.Likely,
Spoof = Likelihood.Likely,
Violence = Likelihood.Likely
}
};
// Act
var googleCloudVisionService = new GoogleCloudVisionService(mockOptions.Object, Options.Create(googleCloudVisionSettings));
var isSafe = await googleCloudVisionService.IsImageSafe(faker.Random.Bytes(512));
// Assert
Assert.True(isSafe);
}
[Fact]
public async Task GivenUnsafeImage_ShouldReturnFalse()
{
// Arrange
var faker = new Faker();
var expectedAnnotation = new SafeSearchAnnotation
{
Adult = Likelihood.VeryLikely,
Racy = Likelihood.VeryLikely,
Medical = Likelihood.VeryLikely,
Spoof = Likelihood.VeryLikely,
Violence = Likelihood.VeryLikely
};
var mockOptions = new Mock<ImageAnnotatorClient>();
mockOptions.Setup(mock => mock.DetectSafeSearchAsync(It.IsAny<Image>(), It.IsAny<ImageContext>(), It.IsAny<CallSettings>()))
.ReturnsAsync(expectedAnnotation);
var json = JsonConvert.SerializeObject(api);
byte[] bytes = Encoding.Default.GetBytes(json);
var googleCloudVisionSettings = new GoogleCloudVisionSettings
{
Key = Convert.ToBase64String(bytes),
Annotations = new Annotations
{
Adult = Likelihood.Likely,
Racy = Likelihood.Likely,
Medical = Likelihood.Likely,
Spoof = Likelihood.Likely,
Violence = Likelihood.Likely
}
};
// Act
var googleCloudVisionService = new GoogleCloudVisionService(mockOptions.Object, Options.Create(googleCloudVisionSettings));
var isSafe = await googleCloudVisionService.IsImageSafe(faker.Random.Bytes(512));
// Assert
Assert.False(isSafe);
}
}
To make it mock-able, I need to add a new constructor so I can pass an instance of Mock<ImageAnnotatorClient>
public GoogleCloudVisionService(ImageAnnotatorClient client, IOptions<GoogleCloudVisionSettings> googleCloudVisionSettings)
{
this.client = client;
this.googleCloudVisionSettings = googleCloudVisionSettings.Value.WithParsedKey();
}

Related

Unification of the 2 methods

I need some help. I need to combine these two methods into one and I can't figure out how.
I tried with an IF statement (we checked if employeeMark is NullOrEmpty, we use the first logic and if it's not, the second logic) but it's just duplicated code in one method instead of two.
This is the first method :
private async Task<ProcessedContractsIdentifiers> GetContractsIdentifiersByContractsCodes(List<ImportableContractIdentifier> importableContractsIdentifiers)
{
var errors = new List<ContractImportValidationErrorDto>();
foreach (var contract in importableContractsIdentifiers.Where(contract => string.IsNullOrWhiteSpace(contract.ContractCode)))
{
errors.Add(new ContractImportValidationErrorDto
{
ValidatedCode = string.Empty,
Line = contract.RowNumber,
ErrorCode = ContractImportValidationErrorCode.ContractCodeIsRequired
});
}
var contractsCodes = importableContractsIdentifiers.ConvertAll(x => x.ContractCode);
contractsCodes = contractsCodes.Where(x => !string.IsNullOrWhiteSpace(x)).ToList();
var contractsSignatures = await GetContractsSignaturesByContractsCodes(contractsCodes);
var unresolvedContracts = contractsCodes.Except(contractsSignatures.Select(cs => cs.Code)).ToHashSet();
foreach (var c in unresolvedContracts)
{
errors.Add(new ContractImportValidationErrorDto
{
ValidatedCode = c,
ErrorCode = ContractImportValidationErrorCode.InvalidContractCode
});
}
return new ProcessedContractsIdentifiers
{
IdentificationMethod = ContractIdentificationMethod.ByContractCode,
IdentifiedContractsSignatures = contractsSignatures,
NonIdentifiableContracts = errors
};
}
And this is the second method :
private async Task<ProcessedContractsIdentifiers> GetContractsIdentifiersByEmployeesMarks(List<ImportableContractIdentifier> importableContractsIdentifiers)
{
const int withSingleContract = 1;
var errors = new List<ContractImportValidationErrorDto>();
foreach (var contract in importableContractsIdentifiers.Where(contract => string.IsNullOrWhiteSpace(contract.EmployeeMark)))
{
errors.Add(new ContractImportValidationErrorDto
{
ValidatedCode = string.Empty,
Line = contract.RowNumber,
ErrorCode = ContractImportValidationErrorCode.EmployeeMarkIsRequired
});
}
var employeesMarks = importableContractsIdentifiers.Select(x => x.EmployeeMark).Where(x => !string.IsNullOrWhiteSpace(x)).ToHashSet();
var contractsSignatures = await GetContractsSignaturesByEmployeeMark(employeesMarks);
var contractsGroupedByEmployeeMark = contractsSignatures.GroupBy(x => x.EmployeeMark);
foreach (var contracts in contractsGroupedByEmployeeMark.Where(x => x.ToList().Count != withSingleContract))
{
errors.Add(new ContractImportValidationErrorDto
{
ValidatedCode = contracts.Key,
ErrorCode = ContractImportValidationErrorCode.EmployeeMarkWithMultipleContracts
});
}
var unresolvedMarks = employeesMarks.Except(contractsSignatures.Select(cs => cs.EmployeeMark)).ToHashSet();
foreach (var eMark in unresolvedMarks)
{
errors.Add(new ContractImportValidationErrorDto
{
ValidatedCode = eMark,
ErrorCode = ContractImportValidationErrorCode.InvalidEmployeeMark
});
}
return new ProcessedContractsIdentifiers
{
IdentificationMethod = ContractIdentificationMethod.ByEmployeeMark,
IdentifiedContractsSignatures = contractsSignatures,
NonIdentifiableContracts = errors
};
}
Use Enum as parameter, so according to its value you can write code blocks.
public Enum IOMode
{
In=0,
Out=1
}
public void CalculateAttendance(List<Log> lstLog, IOMode eIOMode)
{
if(eIOMode==IOMode.In)
{}
else
{ }
}
call CalculateAttendance(lstLog, IOMode.In) etc

Adding a wall with an opening Xbim

I am looking to adjust the template project to add an opening for the door so the door will be flush with the wall system instead of appearing embedded in the skin of the wall any help would be very appreciated.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Xbim.Common;
using Xbim.Common.Step21;
using Xbim.Ifc;
using Xbim.IO;
using Xbim.Ifc4.ActorResource;
using Xbim.Ifc4.DateTimeResource;
using Xbim.Ifc4.ExternalReferenceResource;
using Xbim.Ifc4.PresentationOrganizationResource;
using Xbim.Ifc4.GeometricConstraintResource;
using Xbim.Ifc4.GeometricModelResource;
using Xbim.Ifc4.GeometryResource;
using Xbim.Ifc4.Interfaces;
using Xbim.Ifc4.Kernel;
using Xbim.Ifc4.MaterialResource;
using Xbim.Ifc4.MeasureResource;
using Xbim.Ifc4.ProductExtension;
using Xbim.Ifc4.ProfileResource;
using Xbim.Ifc4.PropertyResource;
using Xbim.Ifc4.QuantityResource;
using Xbim.Ifc4.RepresentationResource;
using Xbim.Ifc4.SharedBldgElements;
namespace HelloWall
{
class Program
{
/// <summary>
/// This sample demonstrates the minimum steps to create a compliant IFC model that contains a single standard case wall
/// </summary>
static int Main()
{
//first create and initialise a model called Hello Wall
Console.WriteLine("Initialising the IFC Project....");
using (var model = CreateandInitModel("HelloWall"))
{
if (model != null)
{
IfcBuilding building = CreateBuilding(model, "Default Building");
IfcWallStandardCase wall = CreateWall(model, 4000, 300, 2400);
if (wall != null) AddPropertiesToWall(model, wall);
using (var txn = model.BeginTransaction("Add Wall"))
{
building.AddElement(wall);
txn.Commit();
}
if (wall != null)
{
try
{
Console.WriteLine("Standard Wall successfully created....");
//write the Ifc File
model.SaveAs("HelloWallIfc4.ifc", IfcStorageType.Ifc);
Console.WriteLine("HelloWallIfc4.ifc has been successfully written");
}
catch (Exception e)
{
Console.WriteLine("Failed to save HelloWall.ifc");
Console.WriteLine(e.Message);
}
}
}
else
{
Console.WriteLine("Failed to initialise the model");
}
}
Console.WriteLine("Press any key to exit to view the IFC file....");
Console.ReadKey();
LaunchNotepad("HelloWallIfc4.ifc");
return 0;
}
private static void LaunchNotepad(string fileName)
{
Process p;
try
{
p = new Process {StartInfo = {FileName = fileName, CreateNoWindow = false}};
p.Start();
}
catch (Exception ex)
{
Console.WriteLine("Exception Occurred :{0},{1}",
ex.Message, ex.StackTrace);
}
}
private static IfcBuilding CreateBuilding(IfcStore model, string name)
{
using (var txn = model.BeginTransaction("Create Building"))
{
var building = model.Instances.New<IfcBuilding>();
building.Name = name;
building.CompositionType = IfcElementCompositionEnum.ELEMENT;
var localPlacement = model.Instances.New<IfcLocalPlacement>();
building.ObjectPlacement = localPlacement;
var placement = model.Instances.New<IfcAxis2Placement3D>();
localPlacement.RelativePlacement = placement;
placement.Location = model.Instances.New<IfcCartesianPoint>(p=>p.SetXYZ(0,0,0));
//get the project there should only be one and it should exist
var project = model.Instances.OfType<IfcProject>().FirstOrDefault();
project?.AddBuilding(building);
txn.Commit();
return building;
}
}
/// <summary>
/// Sets up the basic parameters any model must provide, units, ownership etc
/// </summary>
/// <param name="projectName">Name of the project</param>
/// <returns></returns>
private static IfcStore CreateandInitModel(string projectName)
{
//first we need to set up some credentials for ownership of data in the new model
var credentials = new XbimEditorCredentials
{
ApplicationDevelopersName = "xbim developer",
ApplicationFullName = "Hello Wall Application",
ApplicationIdentifier = "HelloWall.exe",
ApplicationVersion = "1.0",
EditorsFamilyName = "Team",
EditorsGivenName = "xbim",
EditorsOrganisationName = "xbim developer"
};
//now we can create an IfcStore, it is in Ifc4 format and will be held in memory rather than in a database
//database is normally better in performance terms if the model is large >50MB of Ifc or if robust transactions are required
var model = IfcStore.Create(credentials, IfcSchemaVersion.Ifc4,XbimStoreType.InMemoryModel);
//Begin a transaction as all changes to a model are ACID
using (var txn = model.BeginTransaction("Initialise Model"))
{
//create a project
var project = model.Instances.New<IfcProject>();
//set the units to SI (mm and metres)
project.Initialize(ProjectUnits.SIUnitsUK);
project.Name = projectName;
//now commit the changes, else they will be rolled back at the end of the scope of the using statement
txn.Commit();
}
return model;
}
/// <summary>
/// This creates a wall and it's geometry, many geometric representations are possible and extruded rectangular footprint is chosen as this is commonly used for standard case walls
/// </summary>
/// <param name="model"></param>
/// <param name="length">Length of the rectangular footprint</param>
/// <param name="width">Width of the rectangular footprint (width of the wall)</param>
/// <param name="height">Height to extrude the wall, extrusion is vertical</param>
/// <returns></returns>
static private IfcWallStandardCase CreateWall(IfcStore model, double length, double width, double height)
{
//
//begin a transaction
using (var txn = model.BeginTransaction("Create Wall"))
{
var wall = model.Instances.New<IfcWallStandardCase>();
wall.Name = "A Standard rectangular wall";
//represent wall as a rectangular profile
var rectProf = model.Instances.New<IfcRectangleProfileDef>();
rectProf.ProfileType = IfcProfileTypeEnum.AREA;
rectProf.XDim = width;
rectProf.YDim = length;
var insertPoint = model.Instances.New<IfcCartesianPoint>();
insertPoint.SetXY(0, 400); //insert at arbitrary position
rectProf.Position = model.Instances.New<IfcAxis2Placement2D>();
rectProf.Position.Location = insertPoint;
//model as a swept area solid
var body = model.Instances.New<IfcExtrudedAreaSolid>();
body.Depth = height;
body.SweptArea = rectProf;
body.ExtrudedDirection = model.Instances.New<IfcDirection>();
body.ExtrudedDirection.SetXYZ(0, 0, 1);
//parameters to insert the geometry in the model
var origin = model.Instances.New<IfcCartesianPoint>();
origin.SetXYZ(0, 0, 0);
body.Position = model.Instances.New<IfcAxis2Placement3D>();
body.Position.Location = origin;
//Create a Definition shape to hold the geometry
var shape = model.Instances.New<IfcShapeRepresentation>();
var modelContext = model.Instances.OfType<IfcGeometricRepresentationContext>().FirstOrDefault();
shape.ContextOfItems = modelContext;
shape.RepresentationType = "SweptSolid";
shape.RepresentationIdentifier = "Body";
shape.Items.Add(body);
//Create a Product Definition and add the model geometry to the wall
var rep = model.Instances.New<IfcProductDefinitionShape>();
rep.Representations.Add(shape);
wall.Representation = rep;
//now place the wall into the model
var lp = model.Instances.New<IfcLocalPlacement>();
var ax3D = model.Instances.New<IfcAxis2Placement3D>();
ax3D.Location = origin;
ax3D.RefDirection = model.Instances.New<IfcDirection>();
ax3D.RefDirection.SetXYZ(0, 1, 0);
ax3D.Axis = model.Instances.New<IfcDirection>();
ax3D.Axis.SetXYZ(0, 0, 1);
lp.RelativePlacement = ax3D;
wall.ObjectPlacement = lp;
// Where Clause: The IfcWallStandard relies on the provision of an IfcMaterialLayerSetUsage
var ifcMaterialLayerSetUsage = model.Instances.New<IfcMaterialLayerSetUsage>();
var ifcMaterialLayerSet = model.Instances.New<IfcMaterialLayerSet>();
var ifcMaterialLayer = model.Instances.New<IfcMaterialLayer>();
ifcMaterialLayer.LayerThickness = 10;
ifcMaterialLayerSet.MaterialLayers.Add(ifcMaterialLayer);
ifcMaterialLayerSetUsage.ForLayerSet = ifcMaterialLayerSet;
ifcMaterialLayerSetUsage.LayerSetDirection = IfcLayerSetDirectionEnum.AXIS2;
ifcMaterialLayerSetUsage.DirectionSense = IfcDirectionSenseEnum.NEGATIVE;
ifcMaterialLayerSetUsage.OffsetFromReferenceLine = 150;
// Add material to wall
var material = model.Instances.New<IfcMaterial>();
material.Name = "some material";
var ifcRelAssociatesMaterial = model.Instances.New<IfcRelAssociatesMaterial>();
ifcRelAssociatesMaterial.RelatingMaterial = material;
ifcRelAssociatesMaterial.RelatedObjects.Add(wall);
ifcRelAssociatesMaterial.RelatingMaterial = ifcMaterialLayerSetUsage;
// IfcPresentationLayerAssignment is required for CAD presentation in IfcWall or IfcWallStandardCase
var ifcPresentationLayerAssignment = model.Instances.New<IfcPresentationLayerAssignment>();
ifcPresentationLayerAssignment.Name = "some ifcPresentationLayerAssignment";
ifcPresentationLayerAssignment.AssignedItems.Add(shape);
// linear segment as IfcPolyline with two points is required for IfcWall
var ifcPolyline = model.Instances.New<IfcPolyline>();
var startPoint = model.Instances.New<IfcCartesianPoint>();
startPoint.SetXY(0, 0);
var endPoint = model.Instances.New<IfcCartesianPoint>();
endPoint.SetXY(4000, 0);
ifcPolyline.Points.Add(startPoint);
ifcPolyline.Points.Add(endPoint);
var shape2D = model.Instances.New<IfcShapeRepresentation>();
shape2D.ContextOfItems = modelContext;
shape2D.RepresentationIdentifier = "Axis";
shape2D.RepresentationType = "Curve2D";
shape2D.Items.Add(ifcPolyline);
rep.Representations.Add(shape2D);
txn.Commit();
return wall;
}
}
/// <summary>
/// Add some properties to the wall,
/// </summary>
/// <param name="model">XbimModel</param>
/// <param name="wall"></param>
static private void AddPropertiesToWall(IfcStore model, IfcWallStandardCase wall)
{
using (var txn = model.BeginTransaction("Create Wall"))
{
CreateElementQuantity(model, wall);
CreateSimpleProperty(model, wall);
txn.Commit();
}
}
private static void CreateSimpleProperty(IfcStore model, IfcWallStandardCase wall)
{
var ifcPropertySingleValue = model.Instances.New<IfcPropertySingleValue>(psv =>
{
psv.Name = "IfcPropertySingleValue:Time";
psv.Description = "";
psv.NominalValue = new IfcTimeMeasure(150.0);
psv.Unit = model.Instances.New<IfcSIUnit>(siu =>
{
siu.UnitType = IfcUnitEnum.TIMEUNIT;
siu.Name = IfcSIUnitName.SECOND;
});
});
var ifcPropertyEnumeratedValue = model.Instances.New<IfcPropertyEnumeratedValue>(pev =>
{
pev.Name = "IfcPropertyEnumeratedValue:Music";
pev.EnumerationReference = model.Instances.New<IfcPropertyEnumeration>(pe =>
{
pe.Name = "Notes";
pe.EnumerationValues.Add(new IfcLabel("Do"));
pe.EnumerationValues.Add(new IfcLabel("Re"));
pe.EnumerationValues.Add(new IfcLabel("Mi"));
pe.EnumerationValues.Add(new IfcLabel("Fa"));
pe.EnumerationValues.Add(new IfcLabel("So"));
pe.EnumerationValues.Add(new IfcLabel("La"));
pe.EnumerationValues.Add(new IfcLabel("Ti"));
});
pev.EnumerationValues.Add(new IfcLabel("Do"));
pev.EnumerationValues.Add(new IfcLabel("Re"));
pev.EnumerationValues.Add(new IfcLabel("Mi"));
});
var ifcPropertyBoundedValue = model.Instances.New<IfcPropertyBoundedValue>(pbv =>
{
pbv.Name = "IfcPropertyBoundedValue:Mass";
pbv.Description = "";
pbv.UpperBoundValue = new IfcMassMeasure(5000.0);
pbv.LowerBoundValue = new IfcMassMeasure(1000.0);
pbv.Unit = model.Instances.New<IfcSIUnit>(siu =>
{
siu.UnitType = IfcUnitEnum.MASSUNIT;
siu.Name = IfcSIUnitName.GRAM;
siu.Prefix = IfcSIPrefix.KILO;
});
});
var definingValues = new List<IfcReal> { new IfcReal(100.0), new IfcReal(200.0), new IfcReal(400.0), new IfcReal(800.0), new IfcReal(1600.0), new IfcReal(3200.0), };
var definedValues = new List<IfcReal> { new IfcReal(20.0), new IfcReal(42.0), new IfcReal(46.0), new IfcReal(56.0), new IfcReal(60.0), new IfcReal(65.0), };
var ifcPropertyTableValue = model.Instances.New<IfcPropertyTableValue>(ptv =>
{
ptv.Name = "IfcPropertyTableValue:Sound";
foreach (var item in definingValues)
{
ptv.DefiningValues.Add(item);
}
foreach (var item in definedValues)
{
ptv.DefinedValues.Add(item);
}
ptv.DefinedUnit = model.Instances.New<IfcContextDependentUnit>(cd =>
{
cd.Dimensions = model.Instances.New<IfcDimensionalExponents>(de =>
{
de.LengthExponent = 0;
de.MassExponent = 0;
de.TimeExponent = 0;
de.ElectricCurrentExponent = 0;
de.ThermodynamicTemperatureExponent = 0;
de.AmountOfSubstanceExponent = 0;
de.LuminousIntensityExponent = 0;
});
cd.UnitType = IfcUnitEnum.FREQUENCYUNIT;
cd.Name = "dB";
});
});
var listValues = new List<IfcLabel> { new IfcLabel("Red"), new IfcLabel("Green"), new IfcLabel("Blue"), new IfcLabel("Pink"), new IfcLabel("White"), new IfcLabel("Black"), };
var ifcPropertyListValue = model.Instances.New<IfcPropertyListValue>(plv =>
{
plv.Name = "IfcPropertyListValue:Colours";
foreach (var item in listValues)
{
plv.ListValues.Add(item);
}
});
var ifcMaterial = model.Instances.New<IfcMaterial>(m =>
{
m.Name = "Brick";
});
var ifcPrValueMaterial = model.Instances.New<IfcPropertyReferenceValue>(prv =>
{
prv.Name = "IfcPropertyReferenceValue:Material";
prv.PropertyReference = ifcMaterial;
});
var ifcMaterialList = model.Instances.New<IfcMaterialList>(ml =>
{
ml.Materials.Add(ifcMaterial);
ml.Materials.Add(model.Instances.New<IfcMaterial>(m =>{m.Name = "Cavity";}));
ml.Materials.Add(model.Instances.New<IfcMaterial>(m => { m.Name = "Block"; }));
});
var ifcMaterialLayer = model.Instances.New<IfcMaterialLayer>(ml =>
{
ml.Material = ifcMaterial;
ml.LayerThickness = 100.0;
});
var ifcPrValueMatLayer = model.Instances.New<IfcPropertyReferenceValue>(prv =>
{
prv.Name = "IfcPropertyReferenceValue:MaterialLayer";
prv.PropertyReference = ifcMaterialLayer;
});
var ifcDocumentReference = model.Instances.New<IfcDocumentReference>(dr =>
{
dr.Name = "Document";
dr.Location = "c://Documents//TheDoc.Txt";
});
var ifcPrValueRef = model.Instances.New<IfcPropertyReferenceValue>(prv =>
{
prv.Name = "IfcPropertyReferenceValue:Document";
prv.PropertyReference = ifcDocumentReference;
});
var ifcTimeSeries = model.Instances.New<IfcRegularTimeSeries>(ts =>
{
ts.Name = "Regular Time Series";
ts.Description = "Time series of events";
ts.StartTime = new IfcDateTime("2015-02-14T12:01:01");
ts.EndTime = new IfcDateTime("2015-05-15T12:01:01");
ts.TimeSeriesDataType = IfcTimeSeriesDataTypeEnum.CONTINUOUS;
ts.DataOrigin = IfcDataOriginEnum.MEASURED;
ts.TimeStep = 604800; //7 days in secs
});
var ifcPrValueTimeSeries = model.Instances.New<IfcPropertyReferenceValue>(prv =>
{
prv.Name = "IfcPropertyReferenceValue:TimeSeries";
prv.PropertyReference = ifcTimeSeries;
});
var ifcAddress = model.Instances.New<IfcPostalAddress>(a =>
{
a.InternalLocation = "Room 101";
a.AddressLines.AddRange(new[] { new IfcLabel("12 New road"), new IfcLabel("DoxField" ) });
a.Town = "Sunderland";
a.PostalCode = "DL01 6SX";
});
var ifcPrValueAddress = model.Instances.New<IfcPropertyReferenceValue>(prv =>
{
prv.Name = "IfcPropertyReferenceValue:Address";
prv.PropertyReference = ifcAddress;
});
var ifcTelecomAddress = model.Instances.New<IfcTelecomAddress>(a =>
{
a.TelephoneNumbers.Add(new IfcLabel("01325 6589965"));
a.ElectronicMailAddresses.Add(new IfcLabel("bob#bobsworks.com"));
});
var ifcPrValueTelecom = model.Instances.New<IfcPropertyReferenceValue>(prv =>
{
prv.Name = "IfcPropertyReferenceValue:Telecom";
prv.PropertyReference = ifcTelecomAddress;
});
//lets create the IfcElementQuantity
var ifcPropertySet = model.Instances.New<IfcPropertySet>(ps =>
{
ps.Name = "Test:IfcPropertySet";
ps.Description = "Property Set";
ps.HasProperties.Add(ifcPropertySingleValue);
ps.HasProperties.Add(ifcPropertyEnumeratedValue);
ps.HasProperties.Add(ifcPropertyBoundedValue);
ps.HasProperties.Add(ifcPropertyTableValue);
ps.HasProperties.Add(ifcPropertyListValue);
ps.HasProperties.Add(ifcPrValueMaterial);
ps.HasProperties.Add(ifcPrValueMatLayer);
ps.HasProperties.Add(ifcPrValueRef);
ps.HasProperties.Add(ifcPrValueTimeSeries);
ps.HasProperties.Add(ifcPrValueAddress);
ps.HasProperties.Add(ifcPrValueTelecom);
});
//need to create the relationship
model.Instances.New<IfcRelDefinesByProperties>(rdbp =>
{
rdbp.Name = "Property Association";
rdbp.Description = "IfcPropertySet associated to wall";
rdbp.RelatedObjects.Add(wall);
rdbp.RelatingPropertyDefinition = ifcPropertySet;
});
}
private static void CreateElementQuantity(IfcStore model, IfcWallStandardCase wall)
{
//Create a IfcElementQuantity
//first we need a IfcPhysicalSimpleQuantity,first will use IfcQuantityLength
var ifcQuantityArea = model.Instances.New<IfcQuantityLength>(qa =>
{
qa.Name = "IfcQuantityArea:Area";
qa.Description = "";
qa.Unit = model.Instances.New<IfcSIUnit>(siu =>
{
siu.UnitType = IfcUnitEnum.LENGTHUNIT;
siu.Prefix = IfcSIPrefix.MILLI;
siu.Name = IfcSIUnitName.METRE;
});
qa.LengthValue = 100.0;
});
//next quantity IfcQuantityCount using IfcContextDependentUnit
var ifcContextDependentUnit = model.Instances.New<IfcContextDependentUnit>(cd =>
{
cd.Dimensions = model.Instances.New<IfcDimensionalExponents>(de =>
{
de.LengthExponent = 1;
de.MassExponent = 0;
de.TimeExponent = 0;
de.ElectricCurrentExponent = 0;
de.ThermodynamicTemperatureExponent = 0;
de.AmountOfSubstanceExponent = 0;
de.LuminousIntensityExponent = 0;
});
cd.UnitType = IfcUnitEnum.LENGTHUNIT;
cd.Name = "Elephants";
});
var ifcQuantityCount = model.Instances.New<IfcQuantityCount>(qc =>
{
qc.Name = "IfcQuantityCount:Elephant";
qc.CountValue = 12;
qc.Unit = ifcContextDependentUnit;
});
//next quantity IfcQuantityLength using IfcConversionBasedUnit
var ifcConversionBasedUnit = model.Instances.New<IfcConversionBasedUnit>(cbu =>
{
cbu.ConversionFactor = model.Instances.New<IfcMeasureWithUnit>(mu =>
{
mu.ValueComponent = new IfcRatioMeasure(25.4);
mu.UnitComponent = model.Instances.New<IfcSIUnit>(siu =>
{
siu.UnitType = IfcUnitEnum.LENGTHUNIT;
siu.Prefix = IfcSIPrefix.MILLI;
siu.Name = IfcSIUnitName.METRE;
});
});
cbu.Dimensions = model.Instances.New<IfcDimensionalExponents>(de =>
{
de.LengthExponent = 1;
de.MassExponent = 0;
de.TimeExponent = 0;
de.ElectricCurrentExponent = 0;
de.ThermodynamicTemperatureExponent = 0;
de.AmountOfSubstanceExponent = 0;
de.LuminousIntensityExponent = 0;
});
cbu.UnitType = IfcUnitEnum.LENGTHUNIT;
cbu.Name = "Inch";
});
var ifcQuantityLength = model.Instances.New<IfcQuantityLength>(qa =>
{
qa.Name = "IfcQuantityLength:Length";
qa.Description = "";
qa.Unit = ifcConversionBasedUnit;
qa.LengthValue = 24.0;
});
//lets create the IfcElementQuantity
var ifcElementQuantity = model.Instances.New<IfcElementQuantity>(eq =>
{
eq.Name = "Test:IfcElementQuantity";
eq.Description = "Measurement quantity";
eq.Quantities.Add(ifcQuantityArea);
eq.Quantities.Add(ifcQuantityCount);
eq.Quantities.Add(ifcQuantityLength);
});
//need to create the relationship
model.Instances.New<IfcRelDefinesByProperties>(rdbp =>
{
rdbp.Name = "Area Association";
rdbp.Description = "IfcElementQuantity associated to wall";
rdbp.RelatedObjects.Add(wall);
rdbp.RelatingPropertyDefinition = ifcElementQuantity;
});
}
}
}
I will also have questions about assigning materials in the future but for now, I really need help with the opening.

Loop through dataset by row number

I have a online dataset that I am looping through to save it to a sqlite database. It works well, however the 'count' in which it is sequentially looping through is based on the ID column, however there are instances where the IDs (for the category that I am filtering on) are not sequential. I'd rather loop through row number or similar if possible - but I can't seem to find a way to do it. Below is my code:
Note the count starts at 793 because this is the ID of the first 'surface' categorised record
private async void updateAssetRegisterLocal()
{
try
{
var current = Connectivity.NetworkAccess;
if (current != NetworkAccess.Internet)
{
await DisplayAlert("No Internet Connectivity", "Move to a location with mobile coverage and try again", "OK");
}
else
{
UserDialogs.Instance.ShowLoading();
HttpClient client = new HttpClient();
var response = await client.GetStringAsync("https://XXXX.azurewebsites.net/api/assets");
var onlineAssets = JsonConvert.DeserializeObject<List<AssetRegister>>(response);
var assetsPrelim = onlineAssets
.Where(w => w.Asset_Category == "Surface")
.OrderBy(d => d.ID)
.ToList();
;
using (SQLiteConnection conn = new SQLiteConnection(App.FilePath))
{
try
{
conn.DropTable<AssetRegister>();
}
catch
{
await DisplayAlert("Unsuccessful", "Can't Access", "OK");
}
}
for (int count = 793; count <= (assetsPrelim.Count + 793); count++)
{
var assets = assetsPrelim.Where(x => x.ID == count);
var id = assets.Select(l => l.ID).FirstOrDefault();
var asset_ID = assets.Select(l => l.Asset_ID).FirstOrDefault();
var road_ID = assets.Select(l => l.Road_ID).FirstOrDefault();
var segmentString = assets.Select(l => l.AssetSegmentString).FirstOrDefault();
var hierarchy = assets.Select(l => l.Road_Hierarchy).FirstOrDefault();
var assetCategory = assets.Select(l => l.Asset_Category).FirstOrDefault();
var lat = assets.Select(l => l.Lat).FirstOrDefault();
var inspectionDue = assets.Select(l => l.Inspection_Due).FirstOrDefault();
var lon = assets.Select(l => l.Lon).FirstOrDefault();
var stdRoadId = assets.Select(l => l.StdRoadID).FirstOrDefault();
var assetType = assets.Select(l => l.Asset_Type).FirstOrDefault();
var inspectionDate = assets.Select(l => l.Last_Inspection_Date).FirstOrDefault();
using (SQLiteConnection con = new SQLiteConnection(App.FilePath))
{
con.CreateTable<AssetRegister>();
var assetsLocal = con.Table<AssetRegister>().ToList();
int arlID = assetsLocal.Count + 1;
AssetRegister arl = new AssetRegister()
{
ID = id,
Asset_ID = asset_ID,
Asset_Type = assetType,
Asset_Category = assetCategory,
Road_ID = road_ID,
Road_Hierarchy = hierarchy,
AssetSegmentString = segmentString,
Inspection_Due = inspectionDue,
StdRoadID = stdRoadId,
Lat = lat,
Lon = lon,
Last_Inspection_Date = inspectionDate,
};
using (SQLiteConnection conn = new SQLiteConnection(App.FilePath))
{
conn.CreateTable<AssetRegister>();
int rowsAdded = conn.Insert(arl);
conn.Close();
}
}
}
await DisplayAlert("Success", "Asset Register Updated on Device", "OK");
UserDialogs.Instance.HideLoading();
}
}
catch
{
await DisplayAlert("Error", "Could not get data - Report to System Adminstrator", "OK");
UserDialogs.Instance.HideLoading();
}
}
It looks like you can loop simply iterating using foreach
Instead of
for (int count = 793; count <= (assetsPrelim.Count + 793); count++)
{
var assets = assetsPrelim.Where(x => x.ID == count);
var id = assets.Select(l => l.ID).FirstOrDefault();
var asset_ID = assets.Select(l => l.Asset_ID).FirstOrDefault();
var road_ID = assets.Select(l => l.Road_ID).FirstOrDefault();
var segmentString = assets.Select(l => l.AssetSegmentString).FirstOrDefault();
var hierarchy = assets.Select(l => l.Road_Hierarchy).FirstOrDefault();
var assetCategory = assets.Select(l => l.Asset_Category).FirstOrDefault();
var lat = assets.Select(l => l.Lat).FirstOrDefault();
var inspectionDue = assets.Select(l => l.Inspection_Due).FirstOrDefault();
var lon = assets.Select(l => l.Lon).FirstOrDefault();
var stdRoadId = assets.Select(l => l.StdRoadID).FirstOrDefault();
var assetType = assets.Select(l => l.Asset_Type).FirstOrDefault();
var inspectionDate = assets.Select(l => l.Last_Inspection_Date).FirstOrDefault();
...
you can have
foreach (var asset in assetsPrelim)
{
var id = asset.ID;
var asset_ID = asset.Asset_ID;
var road_ID = assets.Road_ID;
var segmentString = asset.AssetSegmentString;
var hierarchy = asset.Road_Hierarchy;
var assetCategory = asset.Asset_Category;
var lat = asset.Lat;
var inspectionDue = asset.Inspection_Due;
var lon = asset.Lon;
var stdRoadId = asset.StdRoadID;
var assetType = asset.Asset_Type;
var inspectionDate = asset.Last_Inspection_Date;
...
Simply use foreach() instead of for() loop,
for (var asset in assetsPrelim)
{
var id = asset.Id;
var asset_ID = asset.Asset_ID;
var road_ID = assets.Road_ID;
//...
}

Push multiple objects with dynamic data into a DTO and return it

So I'm trying to use a DTO to reshape and return data, it's not working because I'm trying to push in an array of objects (as an IQueryable - which I don't think works) into the DTO, I'm also trying to push in dynamic data into one of the properties, as seen below in the 'hasCurrentUserLiked' property. I need to figure out How to change the objects from IQueryable, into actual objects so they can all be pushed into the DTO and the dynamic data can be worked out.
This is the code
public async Task<PagedList<UserPhoto>> GetSpecificFeed(UserParams userParams)
{
var user = _context.Users.FirstOrDefault(x => x.Username == userParams.u);
var userId = user.Id;
var photos = _context.UserPhotos;
var followerIds = _context.Follows.Where(x => x.FollowerId == userId).Select(x => x.FollowingId).ToList();
var feeds = _context.UserPhotos.Where(x => followerIds.Contains(x.UserId)).OrderByDescending(x => x.DateAdded);
// this doesn't work because 'feeds' is an IQueryable, not an object
var like = await hasCurrentUserLiked(user.Id, feeds.id);
// this has the same problem as above
var feedsToReturn = new FeedsForReturnDto
{
Id = feeds.Id,
PhotoUrl = feeds.photoUrl,
Username = feeds.Username,
Description = feeds.Description,
DateAdded = feeds.DateAdded,
IsImage = feeds.IsImage,
hasCurrentUserLiked = like,
Likes = feeds.Likes
}
return await PagedList<UserPhoto>.CreateAsync(feedsToReturn, userParams.PageNumber, userParams.PageSize);
}
I thought that I might be able to get each image.id in a similar way the 'followerIds' are worked out but I couldn't figure out how to get this to work
[EDIT]
As per Enas Osamas answer, I've changed the code to this and I've debugged it, feedsToReturn has the correct info, so it is doing what its supposed to do. The problem I'm having now is that I'm unable to return it as it can't convert the IEnumerable to an IQueryable. I tried adding an explicit cast but that didn't work, I also tried removing the PagedList, and replacing the type to but this didn't work. My is an IQueryable which might be the problem, I tried changing that to an IEnumerable but this would mess up the code in other places.
This is my new code (still returning 'feeds' instead of 'feedsToReturn', will change when it works)
public async Task<PagedList<UserPhoto>> GetSpecificFeed(UserParams userParams)
{
var user = _context.Users.FirstOrDefault(x => x.Username == userParams.u);
var userId = user.Id;
var photos = _context.UserPhotos;
var followerIds = _context.Follows.Where(x => x.FollowerId == userId).Select(x => x.FollowingId).ToList();
var feeds = _context.UserPhotos.Where(x => followerIds.Contains(x.UserId)).OrderByDescending(x => x.DateAdded);
var feedToReturn = feeds.AsEnumerable().Select(feed => new FeedsForReturnDto
{
Id = feed.Id,
PhotoUrl = feed.photoUrl,
Username = feed.Username,
Description = feed.Description,
DateAdded = feed.DateAdded,
IsImage = feed.IsImage,
hasCurrentUserLiked = hasCurrentUserLiked(user.Id, feed.Id),
Likes = feed.Likes
});
return await PagedList<UserPhoto>.CreateAsync(feeds, userParams.PageNumber, userParams.PageSize);
}
I also tried changing some of the types around and this is what I came up with. The problem here is this:
'System.Collections.Generic.IEnumerable<cartalk.api.Dtos.feeds.FeedsForReturnDto>' to 'System.Linq.IQueryable<System.Collections.IEnumerable>'
and this problem is with the 'feedsToReturn' in the last line
public async Task<PagedList<IEnumerable>> GetSpecificFeed(UserParams userParams)
{
var user = _context.Users.FirstOrDefault(x => x.Username == userParams.u);
var userId = user.Id;
var photos = _context.UserPhotos;
var followerIds = _context.Follows.Where(x => x.FollowerId == userId).Select(x => x.FollowingId).ToList();
var feeds = _context.UserPhotos.Where(x => followerIds.Contains(x.UserId)).OrderByDescending(x => x.DateAdded);
var feedToReturn = feeds.AsEnumerable().Select(feed => new FeedsForReturnDto
{
Id = feed.Id,
PhotoUrl = feed.photoUrl,
Username = feed.Username,
Description = feed.Description,
DateAdded = feed.DateAdded,
IsImage = feed.IsImage,
hasCurrentUserLiked = hasCurrentUserLiked(user.Id, feed.Id),
Likes = feed.Likes
});
return await PagedList<IEnumerable>.CreateAsync(feedToReturn, userParams.PageNumber, userParams.PageSize);
}
PagedList code
public static async Task<PagedList<T>> CreateAsync(IQueryable<T> source,
int pageNumber, int pageSize)
{
var count = await source.CountAsync();
var items = await source.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToListAsync();
return new PagedList<T>(items, count, pageNumber, pageSize);
}
[EDIT]
This is the hasCurrentUserLiked function, it works here
public bool checkCurrentUserLiked(int currentUserId, int imageId)
{
var doesCurrentUserLike = _context.PhotoLikes.Where(x => x.LikerId == currentUserId && x.ImageId == imageId);
var value = true;
if (doesCurrentUserLike == null)
{
value = false;
}
else
{
value = true;
}
return value;
}
You can try something like
feeds.AsEnumerable().Select(feed => new FeedsForReturnDto
{
Id = feed.Id,
PhotoUrl = feed.photoUrl,
Username = feed.Username,
Description = feed.Description,
DateAdded = feed.DateAdded,
IsImage = feed.IsImage,
hasCurrentUserLiked = hasCurrentUserLiked(user.Id, feed.id),
Likes = feed.Likes
});
This would return an IEnumerable containing all the feeds mapped to your DTO after being enumerated to avoid performing operations against the database
[EDIT]
you can maybe do a left join with the _context.PhotoLikes.
Like this
feeds.GroupJoin(_context.PhotoLikes,
f => new { Id = f.Id, UserId = user.Id },
p => new { Id = p.ImageId, UserId = p.LikerId },
(f, p) => new { feed = f, photoLike = p })
.SelectMany(f => f.photoLike.DefaultIfEmpty(),
(f, p) => new FeedsForReturnDto
{
Id = f.feed.Id,
PhotoUrl = f.feed.photoUrl,
Username = f.feed.Username,
Description = f.feed.Description,
DateAdded = f.feed.DateAdded,
IsImage = f.feed.IsImage,
hasCurrentUserLiked = p != null,
Likes = feed.Likes
});
Just note that in this part
f => new { Id = f.Id, UserId = user.Id },
p => new { Id = p.ImageId, UserId = p.LikerId },
the datatypes of properties in both objects must match or it won't compile

How to get Bitcoin Private Key from an ExtPrivKey using NBitcoin

So, I am trying to send some money over using NBitcoin, there is a step where i am failing and that is creating de bitcoin secret to sign the transaction, I have the address, and the ExtPrivKey but i haven't gotten any luck signing it, any recommendation, this is my code below.
var priv = mbwallet.SelectedWallet.PrivateKeys[0].ToWif();
//var ool = new BitcoinSecret(base58, App.Network);
var privkey = mbwallet.SelectedWallet.PrivateKeys[0].PrivateKey.GetBitcoinSecret(App.Network).ToWif();
var key = Key.Parse(privkey, App.Network);
var keysT = key.GetWif(App.Network);
//var myaddress = mbwallet.SelectedWallet.PrivateKeys[0].PrivateKey.PubKey.GetAddress(App.Network);
var myaddress = mbwallet.SelectedWallet.CurrentAddress;
string address = Address.Text;
var destination = BitcoinAddress.Create(address, App.Network);
decimal value = Convert.ToDecimal(Value.Text);
var coins2 = GetCoins(value);
TransactionBuilder txBuilder = new TransactionBuilder();
var tx = txBuilder.AddCoins(coins2)
.AddKeys(keysT)
.SetChange(myaddress)
.Send(destination, new Money(value, MoneyUnit.BTC))
.SendFees("0.0002");
//.BuildTransaction(true);
var tx2 = txBuilder.BuildTransaction(true);
//Console.WriteLine(txBuilder.Verify(tx));
var hello = tx2.ToHex();
var txRepo = new NoSqlTransactionRepository();
//txRepo.Put(tx.GetHash(), tx);
//Assert(txBuilder.Verify(tx)); //check fully signed
List<ICoin> GetCoins(decimal sendAmount)
{
//var mbwallet = (root.DataContext as MainWindowViewModel);
var amountMoney = new Money(sendAmount, MoneyUnit.BTC);
var client = new QBitNinjaClient(App.Network);
var txInAmount = Money.Zero;
var coins1 = new List<ICoin>();
foreach (var balance in client.GetBalance(mbwallet.SelectedWallet.CurrentAddress,//MBWallet.Wallet.Address,
true).Result.Operations)
{
var transactionId = balance.TransactionId;
var transactionResponse =
client.GetTransaction(transactionId).Result;
var receivedCoins = transactionResponse.ReceivedCoins;
foreach (Coin coin in receivedCoins)
{
if (coin.TxOut.ScriptPubKey ==
mbwallet.SelectedWallet.CurrentAddress.ScriptPubKey)//MBWallet.Wallet.BitcoinPrivateKey.ScriptPubKey) // this may not be necessary
{
coins1.Add(coin);
txInAmount += (coin.Amount as Money);
}
}
}
return coins1;
}
For what I see in the code you already add the private key to the builder so basically you only need to sign , something like this
Transaction signed = txBuilder.SignTransaction(tx2);

Categories