valac --vapi --internal-vapi --fast-vapi - vala

// Point.vala
namespace Test {
class Point {
public const int MY_CONST = 123;
public float x { get; set; }
public float y { get; set; }
}
}
There is a vala source file, 'Point.vala'
--vapi
valac --vapi=Point.vapi --library=point -X -shared Point.vala:
// Point.vapi
namespace Test {
}
empty...
--internal-vapi
valac --internal-vapi=Point.vapi --header=Point.h --internal-header=Point_internal.h --library=point -X -shared Point.vala:
// Point.vapi
namespace Test {
[CCode (cheader_filename = "Point_internal.h")]
internal class Point {
public const int MY_CONST;
public Point ();
public float x { get; set; }
public float y { get; set; }
}
}
it seems perfect and works for me
--fast-vapi
valac --fast-vapi=Point.vapi --library=point -X -shared Point.vala:
// Point.vapi
using GLib;
namespace Test {
internal class Point {
public const int MY_CONST = 123; // error
public Point ();
public float x { get; set; }
public float y { get; set; }
}
}
this raises an error, error: External constants cannot use values, when using this vapi
Q1: What is exact difference? and why are there the options.
Q2: For creating shared lib, Should I use --internal-vapi?

Your class doesn't specify its visibility, so it has "internal" visibilty by default.
That means it's only visible to other classes inside your namespace.
If you specify the class as public the --vapi switch will output a vapi files as expected:
// Point.vala
namespace Test {
// Make it public!
public class Point {
public const int MY_CONST = 123;
public float x { get; set; }
public float y { get; set; }
}
}
Invocation:
valac --vapi=Point.vapi --library=point -X -shared Point.vala
Result:
/* Point.vapi generated by valac.exe 0.34.0-dirty, do not modify. */
namespace Test {
[CCode (cheader_filename = "Point.h")]
public class Point {
public const int MY_CONST;
public Point ();
public float x { get; set; }
public float y { get; set; }
}
}
So --vapi will output public types only and --internal-vapi will in addition output internal types as well.
I don't know what --fast-vapi is for.
As to your second question, you should normally use public classes for shared libraries. The whole point of the internal vs public visibility is that public types are meant for consumption by the public (outside the namespace) while internal types are meant for internal implementation details only.

Related

copy contents of dto to another similar dto

I have 2 very similar dto object. I have shown a sample code below, but the actual 2 dto with which I am working have 39 and 40 properties in it.
My question is that is there an easier way to copy contents of QuoteDto to Quote2Dto.
I am makinga call to a legacy project which gives me QuoteDto object. I than have to make call to a new rest service project which only accepts Quote2Dto object
Let me know if you need any more code.
public abstract class QuoteDto
{
public virtual bool IsWaive { get; set; }
public virtual bool IsExpired { get; set; }
}
public abstract class Quote2Dto
{
public virtual bool IsWaive { get; set; }
public virtual bool IsExpired { get; set; }
public virtual bool IsCancel { get; set; }
}
Usually Automapper (or similar library) is used. It can copy same properties without any pre-configuration needed. But you can always configure more advanced property mappings.
Here you can find Getting Started Guide.
You have two options here.
Your first options is to use AutoMapper to copy properties. There are some advanced configurations to AutoMapper if you would need more advanced configuration.
The second option is to create a method inside your DTO, that takes the other DTO and copies the properties.(Basically copying the properties manually.)
It would look something like this:
class FirstSampleDTO
{
public int RandomProperty { get; set; }
public int RandomProperty2 { get; set; }
public int RandomProperty3 { get; set; }
private void CopyDTOData(SecondSampleDTO dto)
{
dto.RandomProperty = this.RandomProperty;
dto.RandomProperty2 = this.RandomProperty2;
dto.RandomProperty3 = this.RandomProperty3;
}
}
class SecondSampleDTO
{
public int RandomProperty { get; set; }
public int RandomProperty2 { get; set; }
public int RandomProperty3 { get; set; }
private void CopyDTOData(FirstSampleDTO dto)
{
dto.RandomProperty = this.RandomProperty;
dto.RandomProperty2 = this.RandomProperty2;
dto.RandomProperty3 = this.RandomProperty3;
}
}
(This in in case you already have the data of the dto.)
I would suggest using the second method if you are not going to do that much of a mapping.

How to use table created using TPH in entity framework?

Domain Model
public abstract class BaseClass
{
public int Id { get; set; }
public int Something1 { get; set; }
public int Something2 { get; set; }
public string Something3 { get; set; }
}
public class PQR1 : BaseClass
{
public int value1 { get; set; }
}
public class PQR2 : BaseClass
{
public int value2 { get; set; }
}
public class PQR3 : BaseClass
{
public int value2 { get; set; }
}
Context Class
public class PQRContext : DbContext
{
public PQRContext() : base ("PQR")
{
}
public DbSet<BaseClass> Baseclass { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<BaseClass>().
Map<PQR1>(m => m.Requires("Type").HasValue("Value1"))
.Map<PQR2>(m => m.Requires("Type").HasValue("Value2"))
.Map<PQR3>(m => m.Requires("Type").HasValue("Value3"));
}
}
It'll create table like this:
But I don't know how to use this table while coding, I get stuck like this
So I can't access to another classes like PQR1, PQR2,PQR3 where as I have no reason to insert data into base class which is already abstract.
First option :
You are not restricted on DbSet creations. You can create many DbSet as much as you need for your derived classes like the code below and access them like you will do with other DbSet :
public DbSet<BaseClass> Baseclass { get; set; }
public DbSet<PQR1> PQR1s { get; set; }
public DbSet<PQR2> PQR2s { get; set; }
public DbSet<PQR3> PQR3s { get; set; }
You use the DbSet related to the derived you want for inserting into or requesting your context.
Second option :
For querying your context and get only the desired subclass entities you can use the generic method OfType<T> which act as a filter like this:
var myBaseClassList = myContext.BaseClass; // Retrieve all PQR1, PQR2 and PQR3 entities
var myPQR1List = myContext.BaseClass.OfType<PQR1>(); // Retrieve all PQR1
var myPQR2List = myContext.BaseClass.OfType<PQR2>(); // Retrieve all PQR2
var myPQR3List = myContext.BaseClass.OfType<PQR3>(); // Retrieve all PQR3
For inserting you can create an instance of your derived class and add it directly to your base class DbSet :
var pqr1 = new PQR1() { /* set my properties */ };
myCOntext.BaseClass.Add(pqr1); // EF knows how to insert data for classes that use TPH.

invalid object name 'dbo.EvaluationTerms'

I have two project folders- Proj.Domain.Core.ClassAgg and Proj.Domain.Evaluation.EvaluationAgg which contain my models classes.
My Year class:
namespace Proj.Domain.Core.ClassAgg
{
public class Year
{
public Year()
{
EvaluationTerms = new List<EvaluationTerm>();
}
public int Id {get;set;}
public int ClassGroupId { get; set; }
public int AcademicYearId { get; set; }
public int NumDivisions { get; set; }
public int PlannedStrength { get; set; }
public virtual ICollection<EvaluationTerm> EvaluationTerms { get; private set; }
}
}
My EvaluationTerm class in different project:
namespace Proj.Domain.Evaluation.EvaluationAgg
{
public class EvaluationTerm
{
public int Id {get;set;}
public int YearId { get; set; }
public string Description { get; set; }
}
}
Proj.Domain.Core.ClassAgg has reference to Proj.Domain.Evaluation.EvaluationAgg.
I am trying to access ClassYear collection from service class in Proj.Domain.Evaluation.EvaluationAgg.
namespace Proj.Application.Core.ClassSvc
{
public class YearService : IYearService
{
private readonly IYearRepository _yearRepository;
public YearService(IClassYearRepository yearRepository)
{
_yearRepository = yearRepository;
}
public List<Year> GetYears()
{
return _yearRepository.GetAll();
}
}
}
Even if I reference Year namespace in Application project, I am not able to retrieve EvaluationTerm data as it is in different project.
Error:
In collection.
invalid object name 'dbo.EvaluationTerms'.

Using ContentPartRecord causes runtime error

I am trying to add a widget to an Orchard site and I made a new content part that inherits from ContentPartRecord. It builds just fine but when I go to run Orchard.exe or when I browse to the site I get this error:
Exception Details: NHibernate.MappingException: Association references unmapped class: System.string
Here is my class:
using System.ComponentModel.DataAnnotations;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Records;
using System.Collections.Generic;
namespace Hjn.Models
{
public class PropertySearchRecord : ContentPartRecord
{
public virtual List<string> PropertyTypes { get; set; }
public virtual List<string> Locations { get; set; }
public virtual List<double> MinimumPrices { get; set; }
public virtual List<double> MaximumPrices { get; set; }
}
public class PropertySearchPart : ContentPart<PropertySearchRecord>
{
[Required]
public List<string> PropertyTypes
{
get { return Record.PropertyTypes; }
set { Record.PropertyTypes = value; }
}
[Required]
public List<string> Locations
{
get { return Record.Locations; }
set { Record.Locations = value; }
}
[Required]
public List<double> MinimumPrices
{
get { return Record.MinimumPrices; }
set { Record.MinimumPrices = value; }
}
[Required]
public List<double> MaximumPrices
{
get { return Record.MaximumPrices; }
set { Record.MaximumPrices = value; }
}
}
}
I'm pretty lost with this one.
I can post the stack trace too if you'd like. Just let me know. Thanks!
Yes, don't use List<> types for your columns. Instead, manage them as n-n relationships. There is a doc topic on that: http://docs.orchardproject.net/Documentation/Creating-1-n-and-n-n-relations

Problem auto mapping => collection of view models instead another view model

I have something like this
public class AViewModel
{
public decimal number { get; set; }
public List<BViewModel> BVM { get; set; }
}
public class BViewModel
{
public string someString{ get; set; }
}
public class SomeObject
{
public decimal number { get; set; }
public List<OtherObjects> BVM { get; set; }
}
public class OtherObjects {
public string someString{ get; set; }
}
Mapper.CreateMap<SomeObject,AViewModel>();
When I have this I get
Trying to map OtherObjects to BViewModel
Using mapping configuration for SomeObject to AViewModel
Destination property: BVM
Missing type map configuration or unsupported mapping.
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown.
How can I help it figure out how to map it properly?
I believe Automapper needs to know how to convert OtherObject to BViewModel. Try adding a mapping for that too.
You need to specify a typeconverter between OtherObject and BViewModel by specifying a custom type converter
Here's what the converter would look like:
public class OtherToBViewTypeConverter : ITypeConverter<OtherObjects, BViewModel>
{
public BViewModel Convert(ResolutionContext context)
{
if (context.IsSourceValueNull) return null;
var otherObjects = context.SourceValue as OtherObjects;
return new BViewModel { someString = otherObjects.someString; }
}
}
And then the map would be called like this:
Mapper.CreateMap<SomeObject,AViewModel>().ConvertUsing<OtherToBViewTypeConverter>();

Resources