Giter VIP home page Giter VIP logo

mapster's Introduction

Mapster Icon

Mapster - The Mapper of Your Domain

Writing mapping methods is a machine job. Do not waste your time, let Mapster do it.

NuGet

Installation

Install Mapster with the NuGet CLI:

Install-Package Mapster

Or use the .NET core CLI to install Mapster:

dotnet add package Mapster

Basic usage

Mapping to a new object

Mapster creates the destination object and maps values to it.

var destObject = sourceObject.Adapt<Destination>();

Mapping to an existing object

You create the object, Mapster maps to the object.

sourceObject.Adapt(destObject);

You can get IMapper instance via dependency injection so you do not have to change code when migrating to mapster from automapper

Add Mapster to service collection

services.AddMapster();

And use it with DI

public class Test
{
    public Test(IMapper mapper)
    {
        var sourceObject = mapper.Adapt<Destination>();
    }
}

Queryable Extensions

Mapster also provides extensions to map queryables.

using (MyDbContext context = new MyDbContext())
{
    // Build a Select Expression from DTO
    var destinations = context.Sources.ProjectToType<Destination>().ToList();

    // Versus creating by hand:
    var destinations = context.Sources.Select(c => new Destination {
        Id = c.Id,
        Name = c.Name,
        Surname = c.Surname,
        ....
    })
    .ToList();
}

Generating models & mappers

No need to write your own DTO classes. Mapster provides Mapster.Tool to help you generating models. And if you would like to have explicit mapping, Mapster also generates mapper class for you.

[AdaptTo("[name]Dto"), GenerateMapper]
public class Student {
    ...
}

Then Mapster will generate:

public class StudentDto {
    ...
}
public static class StudentMapper {
    public static StudentDto AdaptToDto(this Student poco) { ... }
    public static StudentDto AdaptTo(this Student poco, StudentDto dto) { ... }
    public static Expression<Func<Student, StudentDto>> ProjectToDto => ...
}

What's new

Why Mapster?

Performance & Memory efficient

Mapster was designed to be efficient on both speed and memory. You could gain a 4x performance improvement whilst using only 1/3 of memory. And you could gain up to 12x faster performance with

Method Mean StdDev Error Gen 0 Gen 1 Gen 2 Allocated
'Mapster 6.0.0' 108.59 ms 1.198 ms 1.811 ms 31000.0000 - - 124.36 MB
'Mapster 6.0.0 (Roslyn)' 38.45 ms 0.494 ms 0.830 ms 31142.8571 - - 124.36 MB
'Mapster 6.0.0 (FEC)' 37.03 ms 0.281 ms 0.472 ms 29642.8571 - - 118.26 MB
'Mapster 6.0.0 (Codegen)' 34.16 ms 0.209 ms 0.316 ms 31133.3333 - - 124.36 MB
'ExpressMapper 1.9.1' 205.78 ms 5.357 ms 8.098 ms 59000.0000 - - 236.51 MB
'AutoMapper 10.0.0' 420.97 ms 23.266 ms 35.174 ms 87000.0000 - - 350.95 MB

Step into debugging

Step-into debugging lets you debug your mapping and inspect values just like your code. image

Code Generation

Code generation allows you to

  • Validate mapping at compile time
  • Getting raw performance
  • Seeing your mapping code & debugging
  • Finding usage of your models' properties

There are currently two tools which you can choose based on your preferences.

Change logs

https://github.com/MapsterMapper/Mapster/releases

Usages

Acknowledgements

JetBrains kindly provides Mapster with a free open-source licence for their Resharper and Rider.

  • Resharper makes Visual Studio a much better IDE
  • Rider is fast & powerful cross platform .NET IDE

image

mapster's People

Contributors

alifeofkaizen avatar andrerav avatar bryant1410 avatar burgyn avatar chaowlert avatar cmann-andagon avatar dependabot[bot] avatar devbased avatar eric-swann-q2 avatar eswann avatar foriequal0 avatar gritcsenko avatar hoseinhabibiyan avatar hpcsc avatar joshslark avatar keschercode avatar klesouza avatar mehmetemineker avatar misterozzy avatar msadeqsirjani avatar napalu avatar noelmugnier avatar philippe-laval avatar psynomorph avatar r-52 avatar satano avatar sergergood avatar stormaref avatar sven-n avatar wk-j avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mapster's Issues

Post mapping action hook

Is it possible to perform some global post mapping hook? e.g. on a
Config<Foo,Bar> I want to add something like this:

Config<Foo,Bar>.ForType()
.AfterMapping ( Func<Foo,Bar, Bar>)

which receives the input and already mapped output and returns updated output instance.

This allows me to add custom lambda and perform some mapping steps that are naturally not supported by Mapster but I need to implement that logic for every mapping action.
Simple example - Bar need to validate its new state, e.g. I want to call Bar.ValidateSelf() there.
Or I can perform some manual mapping from Foo to some complex Bar properties that are not naturally supported yet.

I understand that this concept may be very unnatural and stimulate some bad practices, but such valuable hook may help in many valid cases to

Mapping complex collection to flattened collection

It's be nice to have an example on how to map things like property of type Dictionary<string,Foo> into List with internal mapping like Foo->Bar with defaults but Bar.ParentKey receives value from Key in KeyValuePair<string,Foo>.
I've tried few options but struggling to get it working. Although it looks like very simple scenario, default mappings from Foo to Bar are not being used or lost (or I'm doing something wrong).

The specified type member '<Property>' is not supported in LINQ to Entities

I just recently stubmled across this great library, but ran into a possible limitation (most likely a Entity Framework limitation) but I was wondering if this is a case that could be covered with Mapster.

Take this Entity and DTO:

public class Site
{
    public Guid Id { get; set; }

    public double[] Extent => new[] {ExtentMinX, ExtentMinY, ExtentMaxX, ExtentMaxY};

    public double ExtentMinX { get; set; }

    public double ExtentMinY { get; set; }

    public double ExtentMaxX { get; set; }

    public double ExtentMaxY { get; set; }
}

public class SiteView
{
    public double[] Extent { get; set; }
}

Throws this exception:

"The specified type member 'Extent' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported."

Using this:

private readonly IEntityReader<Site> _reader;

// ...

return _reader.Query()
                .Where(s => s.Id == query.Id)
                .ProjectToType<SiteView>()
                .SingleOrDefault();

However I can come around this by letting EF finish the operation and map afterwards:

var site = _reader.Query().SingleOrDefault(s => s.Id == query.Id);
return project.Adapt<SiteView>();

Which feels a bit hacky for me, is this something Mapster can handle for me?

All the best,
Jan

Please add support for DateTimeOffset

Trying to map DateTimeOffset gives:

Code:

DateTimeOffset dto1 = DateTimeOffset.UtcNow;
DateTimeOffset dto2 = TypeAdapter.Adapt<DateTimeOffset>(dto1);

Output

Unhandled Exception: System.ArgumentNullException: Value cannot be null.
Parameter name: con
   at System.Reflection.Emit.DynamicILGenerator.Emit(OpCode opcode, ConstructorInfo con)
   at Mapster.Utils.FastObjectFactory.CreateObjectFactory[T](Func`1 factory) in c:\Projects\Mapster\src\Mapster\Utils\FastObjectFactory.cs:line 27
   at Mapster.Adapters.ClassAdapter`2.get_DestinationFactory() in c:\Projects\Mapster\src\Mapster\Adapters\ClassAdapter.cs:line 37
   at Mapster.Adapters.ClassAdapter`2.Adapt(TSource source) in c:\Projects\Mapster\src\Mapster\Adapters\ClassAdapter.cs:line 51
   at (Object , Object[] )
   at Mapster.TypeAdapter.Adapt[TDestination](Object source) in c:\Projects\Mapster\src\Mapster\TypeAdapter.cs:line 22
   at Expressions.Program.Main(String[] args) in c:\Users\Tilt\Documents\Visual Studio 2013\Projects\Expressions\Expressions\Program.cs:line 139

Thanks

Add assembly scanning

Easy addition: Create a simple "IRegister" interface and allow easy assembly scanning for the interface to read all registrations that are present instead of having to manually know/call all mapper registration classes in dependent assemblies.

How to map properties to a virtual property?

First, I want to thank you for the tool.
So, I used to map View Models to POCO classes.
My app has a web api and domain and, beetwen the two layers, I have a VM => POCO mapping.
It's my VM:

public class ProprietarioCrudViewModel // this VM is used do Create and Update
{
    public string Id { get; set; }
    public string PessoaId { get; set; }
    public string Nome { get; set; }
    public string CpfCnpj { get; set; }
    public string RgIe { get; set; }
    public string RgIeUfEmissao { get; set; }
    public DateTime? RgIeDataEmissao { get; set; }
    public string Logradouro { get; set; }
    public string Numero { get; set; }
    public string Bairro { get; set; }
    public string Cep { get; set; }
    public string Complemento { get; set; }
    public string CidadeId { get; set; }
    public string Observacao { get; set; }
    public string Rntrc { get; set; }
    public string SituacaoId { get; set; }
}

It's my POCO:

public partial class Proprietario
{
    public long ProprietarioId { get; set; }
    public long PessoaId { get; set; }
    public string ProprietarioRntrc { get; set; }
    public long SituacaoId { get; set; }

    public virtual Pessoa Pessoa { get; set; }
    public virtual Situacao Situacao { get; set; }
}

 public partial class Pessoa
{
    public long PessoaId { get; set; }
    public long? CidadeId { get; set; }
    public long? PessoaRgIeUfEmissaoId { get; set; }
    public string PessoaNome { get; set; }
    public string PessoaCpfCnpj { get; set; }
    public string PessoaRgIe { get; set; }
    public DateTime? PessoaRgIeDataEmissao { get; set; }
    public string PessoaLogradouro { get; set; }
    public string PessoaNumero { get; set; }
    public string PessoaBairro { get; set; }
    public string PessoaCep { get; set; }
    public string PessoaComplemento { get; set; }
    public string PessoaObservacao { get; set; }

    public virtual Cidade Cidade { get; set; }
    public virtual Estado Estado { get; set; }
}

I try to directly map like:

     TypeAdapterConfig<ProprietarioCrudViewModel, Proprietario>.NewConfig()
            .Map(d => d.ProprietarioId, s => s.Id)
            .Map(d => d.Pessoa.PessoaId, s => s.PessoaId)
            .Map(d => d.Pessoa.PessoaNome, s => s.Nome)
            .Map(d => d.Pessoa.PessoaCpfCnpj, s => s.CpfCnpj)
            .Map(d => d.Pessoa.PessoaRgIe, s => s.RgIe)
            .Map(d => d.Pessoa.PessoaRgIeDataEmissao, s => s.RgIeDataEmissao)
            .Map(d => d.Pessoa.PessoaRgIeUfEmissaoId, s => s.RgIeUfEmissao)
            .Map(d => d.Pessoa.PessoaLogradouro, s => s.Logradouro)
            .Map(d => d.Pessoa.PessoaNumero, s => s.Numero)
            .Map(d => d.Pessoa.PessoaBairro, s => s.Bairro)
            .Map(d => d.Pessoa.PessoaCep, s => s.Cep)
            .Map(d => d.Pessoa.PessoaComplemento, s => s.Complemento)
            .Map(d => d.Pessoa.CidadeId, s => s.CidadeId)
            .Map(d => d.Pessoa.PessoaObservacao, s => s.Observacao)
            .Map(d => d.ProprietarioRntrc, s => s.Rntrc)
            .Map(d => d.SituacaoId, s => s.SituacaoId);

Calling var t = vm.Adapt<Proprietario>();

But t.Pessoa stay null.
I searched but found nothing of the kind in the documentation or I did not see.
Maybe I have not done a deep search.
Thanks for reply.

Proposal - Mapster 3.0

I put this to dump my idea here and for discussion to implement new features.

1. Setting per hierarchy

Currently, Mapster can setup only per type pair. Suppose we have Student and School and those types are related each other, we need to create 2 configs for each type. The idea is we should be able to create only one config.

Suppose we create this setting:

TypeAdapterConfig<Student, StudentDTO>.NewConfig().PreserveReference(true);

The setting should apply to both Student mapping and School mapping. Anyway, if we call TypeAdapter.Adapt<School, SchoolDTO>() above setting should not be applies.

To make V3.0 compatible with V2.0, we could use global setting:

TypeAdapterConfig.GlobalSettings.SettingPerType = true;

Above setting will apply setting per type rather than setting per hierarchy.

2. IgnoreAll & IgnoreNavigationProperties & Include

Now we have Ignore to opt-out properties we wouldn't like to map. The idea is to have opt-in mapping properties. IgnoreAll will ignore all properties. IgnoreNavigationProperties will ignore all properties except primitives. And Include will include properties in mapping even that properties are ignored. This should be useful for projection where normally EF will exclude navigation properties by default and we need to call include to add properties in. We can do following setting.

TypeAdapterConfig.GlobalSettings.Default
                                .When((srcType, destType, mapType) => mapType == MapType.Projection)
                                .IgnoreNavigationProperties(true);

TypeAdapterConfig<Student, StudentDTO>.NewConfig().Include(s => s.Schools);

This IgnoreNavigationProperties & Include setting will also solve #34.

3. Navigation path

The idea is from #35. Map, Ignore, and Include method should accept navigation path, both string and expression. For example:

TypeAdapterConfig<Student, StudentDTO>.NewConfig()
                                      .Include(dest => dest.School.Instructors)
                                      .Map(dest => dest.School.Email, src => src.School.ContactInfo.Email)
                                      .Ignore(dest => dest.School.Name);

4. Inline setting

Currently, we need to separate between config and Adapt method. In some scenario, we might would like to maintain config and Adapt method together. For example:

var result = student.Adapt(config => config.ToType<StudentDTO>().Ignore("Name"));

Inline setting should apply global setting but it should not alter global setting. We can cache setting and compile result using caller information.

For projection, usage might be slightly different.

var result = context.Students.ProjectToType<StudentDTO>(setting => setting.Ignore("Name"));

5. Rename projection method (Done #40)

This should has high impact to everyone who use projection. But in VB, current To method is not fluent.

Dim result = context.Students.Project().To(Of StudentDTO)()

I think To method should be changed to ToType method.

Dim result = context.Students.Project().ToType(Of StudentDTO)()
var result = context.Students.Project().ToType<StudentDTO>();

I haven't prefer VB but I think To method naming is not correct per .NET convention. Another option is to have an alias, but I proposed to rename as it will be less confused.

6. Name mapping strategy (Done #57)

This is for resolving property name. In some cases, we might would like to match proper case to camel case (src.HelloWorld to dest.helloWorld) without manual mapping.

7. Passing run-time value (Done #55)

This is for Mapster to allow passing run-time value ie. this.User.Identity.Name to mapping context.

8. Object to Dictionary & Dictionary to Object (Done #56)

This is to allow conversion between Object and Dictionary.

9. Support dynamic

To convert from/to dynamic.

10. Preserve destination object

Currently when Mapster copy properties from source to destination object, Mapster will create new object for properties. In EF, if we create new navigation objects, EF will create new records. Mapster should preserve object, so when users copy entire object graph, EF will not create new records.

11. Match item when copy list

Continue from 10, when we copy list, Mapster will add new objects to list. EF will create new records for each item. Mapster should be able to identify objects from key and copy to that object.

Unable to add mapster via nuget

Hello,

I'm trying to add mapster via nuget, But every time it failed to install with error

Object reference not set to an instance of an object.

I'm using VS2015 and .Net 4.5.
Here is screenshot.

error

Handling Null source objects

In our coding we have a situation where source object doesn't have any value. E.g. We are getting user information from database, but id pass is not valid, so user object is null.

One way if to sprinkle null check before invoking Adapt method
if (user != null)
{
_adapter.Adapt(user)
}

If there better way to handle Null object in Mapster?

I have seen that AutoMapper supports something like below:
Mapper.CreateMap<User, UserViewModel>()
.ConvertUsing();

class WsMembershipToDeMemberConverter
: AutoMapper.ITypeConverter<User, UserViewModel>
{
public UserViewModel Convert(AutoMapper.ResolutionContext context)
{
if (context == null || context.IsSourceValueNull)
{
return null;
}

    var User = context.SourceValue as User;

    var UserViewModel = new UserViewModel();

    // conversion rules and logics here

    return UserViewModel 
}

}

Do we have any such support? Any thing one can suggest so we don't have to sprinkle null check in entire code base.

Mapping fails

Hello,

I've got an issue when trying to map from one implementation of an interface to another implementation of the same interface.
The ToPocoWithConstuctorWithoutAllProperties fails (It uses only casts the object instead of using the ConstructUsing; thus giving a whole other lamdba expression).

See tests:
WhenMapping.txt

ToPocoWithOnlyConstuctorForAllProperties
GetMergedSettings => result.ConverterFactory.Target == {Mapster.Adapters.RecordTypeAdapter}

.Lambda #Lambda1<System.Func`2[Mapster.Tests.IPoco,Mapster.Tests.ToPocoWithOnlyConstuctorForAllProperties]>(Mapster.Tests.IPoco $var1)
{
.If ($var1 == null) {
null
} .Else {
.New Mapster.Tests.ToPocoWithOnlyConstuctorForAllProperties(
$var1.Id,
$var1.SubId)
}
}

ToPocoWithPrivateSet
GetMergedSettings => result.ConverterFactory.Target == {Mapster.Adapters.ClassAdapter}
.Lambda #Lambda1<System.Func`2[Mapster.Tests.IPoco,Mapster.Tests.ToPocoWithPrivateSet]>(Mapster.Tests.IPoco $var1) {
.If ($var1 == null) {
null
} .Else {
.New Mapster.Tests.ToPocoWithPrivateSet(
$var1.Id,
$var1.SubId){
}
}
}

ToPocoWithConstuctorWithoutAllProperties
GetMergedSettings => result.ConverterFactory.Target == {Mapster.Adapters.PrimitiveAdapter}
.Lambda #Lambda1<System.Func`2[Mapster.Tests.IPoco,Mapster.Tests.ToPocoWithConstuctorWithoutAllProperties]>(Mapster.Tests.IPoco $var1)
{
.If ($var1 == null) {
null
} .Else {
(Mapster.Tests.ToPocoWithConstuctorWithoutAllProperties)$var1
}
}

how to map just derived class properties (and exclude base class)

Hi,
(I'm referring to the 'source' type, I want to avoid mapping all inherited properties from base classes)
I've tried a few things fast, even MapToTargetWith(=> destination) to skip any mapping on the base, but then NoInherit doesn't work (seems) so the derived one is turned off as well (if I'm getting it right).
and btw. Mapster is looking great so far!
Thanks

Ignore Case-sensitivity on Propertynames

It would be nice if mapster can ignore differend Upper/Lowercase naming. I am mapping from a Webservice where lots of things are in uppercase (Id vs ID).

I could not found anything anythin in the settings to ignore the case for the matching names.

ConstructUsing not working when mapping to interfaces

Mapping to interfaces seems not to work.
with
config.ForType<PBPatient, IPatient>() .ConstructUsing(src => new Patient());

I get the following error:

System.ArgumentException : Expression of type 'System.Linq.Expressions.Expression1[System.Func2[PBPatient,Business.Patient]]' cannot be used for parameter of type 'System.Linq.Expressions.Expression1[System.Func2[PBPatient,IPatient]]' of method 'System.Linq.IQueryable1[IPatient] Select[PBPatient,IPatient](System.Linq.IQueryable1[PBPatient], System.Linq.Expressions.Expression1[System.Func2[PBPatient,IPatient]])'
Result StackTrace:
at System.Linq.Expressions.Expression.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arg, ParameterInfo pi)
at System.Linq.Expressions.Expression.Call(MethodInfo method, Expression arg0, Expression arg1)
at Mapster.TypeAdapterConfig.CreateProjectionCallExpression(TypeTuple tuple)
at Mapster.TypeAdapterConfig.Compile()

However if I use
config.ForType<PBPatient, IPatient>() .ConstructUsing(src => new Patient() as IPatient);

I get the following error:

System.InvalidOperationException : Input ConstructUsing is invalid for projection: TSource: PBPatient TDestination: IPatient

Is there a workaround to Support Interfaces?

Question: MapContext used with ProjectToType

Hi,

I use Masper 2.4 an have 2 questions:

  1. I can't use MapContext in my Mapping. I receive an "Inaccesbile due Protection Level" Build Error. What i due i wrong. I have a static Mapper Class to Map the DTO's
  2. How can i use MapContext in combination with ProjectToType?

Thanks for response
Philipp

Mapping ObservableCollection<T> throws error

Mapping ObservableCollection throws exception in ClassAdapter's Adapt-method at:

if (propertyModel.DestinationTransform == null)
{
propertyModel.Setter.Invoke(destination, destinationValue);
}

Anyway to solve this? Did not find a solution at this time...

Instance creation of derived class from an abstract class

Hello @eswann , @chaowlert,

I am facing a particular issue where I have a derived class inheriting from a base abstract class and Mapster give me an error "Instances of abstract classes cannot be created". Consider the example below:

I have a TPT database model, where my Car inherits from Vehicle, my EF model reflects it.

My Dto objects are:


public class ProductDto
{
  public List<VehicleDto> Vehicles { get; set; }
}

[KnownType(typeof(CarDto)]
public abstract class VehicleDto
{
  public int Id { get; set; }
  public string Name { get; set; }
}

public class CarDto : VehicleDto
{
  public string Make { get; set; }
  public string ChassiNumber { get; set; }
}

My Mapping is:

TypeAdapterConfig<Product, ProductDto>.NewConfig(); //Product is a table in db
TypeAdapterConfig<Vehicle, VehicleDto>.NewConfig(); // Vehicle is a table in the db
TypeAdapterConfig<Car, CarDto> // Car is a table in the db
      .NewConfig()
      .Inherits<Vehicle, VehicleDto>;

The actual call

 var product = context.GetProductById(1); // returns the list of Vehicle - containing type Car 
 var productDto = product.Adapt<ProductDto>(); // Exception is throw here. Where I expect my list  of VehicleDto will be mapped (as list of type CarDto)

What wrong am I doing? Is there any mapping registration issue? or Mapster is unable to handle abstract class? Please let me know.

Thanks!

Entity Framework 7 Support, IQueryable Extensions

Hi,

First of all, thank you for such a great library. Just switched from AutoMapper to Mapster, and I think it's awesome.
I have a question regarding the IQueryable extensions using EF7. When I call the Project() method where the underlying ORM is EF7, I am getting an error as follows

Expression of type 'Microsoft.Data.Entity.Query.Internal.EntityQueryable' cannot be used for
parameter of type 'System.Collections.Generic.ICollection`' of method.

Is this a problem because of EF7, or possibly an issue within Mapster? Any ideas? Will be happy to provide more information if necessary.

Thanks!

Mapster modifies underlying collection which is being iterated over, when TypeAdapterConfig.GlobalSettings.Compile() is called.

Hi. Seems that there is an issue with Compile() call.

Mapster is modifying collection when it's being iterated.

The problem happens when there is top level mapping defined between objects, but nested property ( usually a collection of some type) is not defined explicitly).

For the code below:
If I have 3 mappings defined:

MainSrc -> MainDest
List<SrcItem> ->  List<DestItem>
SrcItem -> DestItem

In this case Compile works perfectly

If List<SrcItem> -> List<DestItem> is commented out - it throws vague InvalidOperationException: Collection was modified; enumeration operation may not execute.

This happens because TypeAdapterConfig.GetSettings(x) is not safe - it modifies collection this.RuleMap that is being iterated in TypeAdapterConfig.Compile() call.

// public class TypeAdapterConfig
//...

 private TypeAdapterSettings GetSettings(TypeTuple key)
    {
      TypeAdapterRule typeAdapterRule;
      if (!this.RuleMap.TryGetValue(key, out typeAdapterRule))
      {
        lock (this.RuleMap)
        {
          if (!this.RuleMap.TryGetValue(key, out typeAdapterRule))
          {
            typeAdapterRule = key.Source == typeof (void) ? TypeAdapterConfig.CreateDestinationTypeRule(key) : this.CreateTypeTupleRule(key);
            this.Rules.Add(typeAdapterRule); // <----------- modifies  collection on Read             this.RuleMap.Add(key, typeAdapterRule); // <----------- modifies collection on Read which is being iterated in Compile()

          }
        }
      }
      return typeAdapterRule.Settings;
    }

Here is bug repro example (works well in LinqPad with Mapster and AutoFixture nugets but can be easily converted to a console app):

void Main()
{

    WebDTOMapSetup.Verify();

    var fixt = new Fixture(); 
    var input = fixt.Create<MainSrc>();

    var output = input.Adapt<MainSrc,MainDest>();
    output.Dump();
}

public class WebDTOMapSetup
{
    static WebDTOMapSetup()
    {
        configme();
    }
    private static void configme()
    {

        TypeAdapterConfig<SrcItem, DestItem>.ForType();

        // BUG TRIGGER IS HERE --------> Comment this line to see mapster bug
        TypeAdapterConfig<List<SrcItem>, List<DestItem>>.ForType();

        //Validate globally
        TypeAdapterConfig<MainSrc, MainDest>.ForType()
        .Map(d=>d.DestItems, s=>s.SrcItems)
        ;

        TypeAdapterConfig.GlobalSettings.Compile();
    }

    public static void Verify()
    {
        TypeAdapterConfig.GlobalSettings.Compile();
    }
}

class MainSrc
{
    public int SrcId { get; set; }
    public List<SrcItem> SrcItems { get; set; }
}
class MainDest
{
    public int DestId { get; set; }
    public List<DestItem> DestItems { get; set; }
}
class SrcItem
{
    public int ItemId { get; set; }
    public string StringData { get; set; }
}
class DestItem
{
    public int ItemId { get; set; }
    public string StringData { get; set; }
}

Combine Project and To LINQ projection methods

In AutoMapper, I combined the Project.To into one single method, ProjectTo. This is because IQueryable has an ElementType property, letting you infer TSource. So the final result is something like:

public static IQueryable<TDestination> ProjectTo<TDestination>(this IQueryable source) { }

var results = dbContext.Products.ProjectTo<ProductDto>().ToList();

That extra method call always looked funny but I needed it because you can't do partial generic parameter inference. But you can grab ElementType, no need to supply TSource as a generic parameter, only TDestination. So I obsolete'd the Project.To in favor of ProjectTo (without having to change too much of the internals). I saw you had a suggestion in #38 for a better "To" method, I'd do this first.

Consider making TypeAdapterConfig internal state immutable

I need a way to clone the global typeadapterconfig for an instance config and make it efficient.

Here is the scenario: I have all of my global configuration set for my app. I want to inject an IAdapter per scope that inherits from the global config but adds an adapter rule just for that adapter instance because it's dependent on an item that's injected. If the internal state of the TypeAdapterConfig was comprised of immutable collections, it would make clone operations very fast and updates to the resultant config would not impact the global config.
@chaowlert if you have any ideas on this, would be appreciated.

Autocomplete not working in TypeAdapterConfig<>.Map<> Source

AutoComplete doesn't work in VS2015 when I write TypeAdapterConfig<>.Map<> in Source Parameter. In Destination Parameter it works fine.

It would be nice if it works on source too.

Example:
TypeAdapterConfig<Adresse, AdresseDetailDto>.NewConfig()
.Map(dest => dest**.Id**, source => source.Id)

Max Depth Seems to stop Iteration of List

Hello,

So I am using Entity Framework and I have Goal object that has a reference field of GoalCategory. Now when entity framework returns its it Goal->GoalCategory->Goals->GoalCategory, and this seems to be recersive. So I try to use MaxDepth to stop it at Goal->GoalCategory:

TypeAdapterConfig<DA.Goal, UI.Goal>.NewConfig().MaxDepth(3);
return TypeAdapter.Adapt<IList<UI.Goal>>(list);

But it seems this aftect how many elements in the list are transulated also, because I have a list of 23 and only the first two are translated. if I set max depth to 7, only 6 are translated.

Error for .NetCore

I use Mapster in my .NetCore WebApi project,but when I read the Request.Body ,it made a exception.
When I remove the Mapster,It becomes well.

Still has an issue with mapping dictionaries

Mapster can't map Dictionary<string,Foo> to Dictionary<string,Bar> although there is a valid mapping between Foo and Bar

This is because Dictionary implements IEnumerable which is immutable.

Throws:

Cannot convert immutable type, please consider using 'MapWith' method to create mapping: 
TSource: System.Collections.Generic.KeyValuePair`2[System.String,Foo] 
TDestination: System.Collections.Generic.KeyValuePair`2[System.String,Bar]

Simple configuration like this

TypeAdapterConfig<Dictionary<string, Foo>, Dictionary<string, Bar>>
  .NewConfig()
  .MapWith(x => x.ToDictionary(k => k.Key, v => v.Value.Adapt<Bar>()))

works well and fixes the problem

Is this possible to add such behaviour as default\global for Dictionary and Dictionary<TK,TV> ?

As it's a bit inconvenient to explicitly configure all possible Dictionary combinations..

Not really an issue, but...

Can you provide a really simple, end to end sample asp.net mvc project? i am new to object mappers and i am really struggling with configuration right now and while the readme does tell how the lib functions, there is nothing on how to actually get it up and running

Mapping IDatareader

Hi, is it possible to map result from database from IDataReader to a poco? I have tried but the properties are not set with values. I am busy replacing Automapper with Mapster and really need to get this working. Thanks.

Mapping with Immutable Types

Hello, first of all, thank you very much for this library. It's lighting fast but we are getting an error about immutable types.

namespace MyProject.Test.NoGui.Base.FixtureDatas
{
    public partial class FixtureData
    {
        public class Person
        {
            public IEnumerable<Dictionary<string, BanCause>> OldBans { get; set; }
        }

        public class PersonModel
        {
            public IEnumerable<Dictionary<string, bancausemodel>> OldBans { get; set; }
        }
    }
}

    public partial class FixtureData
    {
        public class BanCause
        {
            public DateTime Date { get; set; }

            public string Cause { get; set; }
        }

        // ReSharper disable InconsistentNaming
        public class bancausemodel
        {
            public DateTime date { get; set; }

            public string cause { get; set; }
        }
        // ReSharper restore InconsistentNaming
    }

Here is the error message from our unit tests;

System.InvalidOperationException: Cannot convert immutable type, please consider using 'MapWith' method to create mapping: TSource: System.Collections.Generic.KeyValuePair2[System.String,MyProject.Test.NoGui.Base.FixtureDatas.FixtureData+BanCause] TDestination: System.Collections.Generic.KeyValuePair2[System.String,MyProject.Test.NoGui.Base.FixtureDatas.FixtureData+bancausemodel]

I already tried MapWith method like;

            //Example of custom TypeAdapterConfig ( Immutable objects )
            TypeAdapterConfig typeAdapterConfig = new TypeAdapterConfig();
            TypeAdapterConfig<BanCause, bancausemodel>.NewConfig()
                                                      .MapWith(src => new bancausemodel());

//or

            //Example of custom TypeAdapterConfig ( Immutable objects )
            TypeAdapterConfig typeAdapterConfig = new TypeAdapterConfig();
            TypeAdapterConfig<Dictionary<string, BanCause>, Dictionary<string, bancausemodel>>.NewConfig()
                                                                                              .MapWith(src => new Dictionary<string, bancausemodel>());

//or

            TypeAdapterConfig<List<Dictionary<string, BanCause>>, List<Dictionary<string, bancausemodel>>>
                .NewConfig()
                .MapWith(src => new List<Dictionary<string, bancausemodel>>());

What am I missing here? Thanks...

Question: Is there any way to debug mappings using logging or TraceSource

Hi, the issues we are hitting with using mapster is that error messages are not very descriptive and it's hard to understand which map is missing or which one is set up incorrectly.

Is there any way to enable logging which can produce human-readable or more detailed output when mapster has an error in mapping. Mapster errors are very generic and don't have any information about what exact type mapping is missing or throwing error. Having a detailed log output like this:
var mappingErrors = TypeAdapterConfig.GlobalSettings.Compile(); would be very helpful.

Or maybe let us to pass some simple logger interface implementation which will be used internally to write detailed information about what's exactly goes wrong:

IMapsterLogger logger = new MyMapsterLogger();
TypeAdapterConfig.GlobalSettings.Compile(logger);

Another option is to have mapster specific TraceSource (which is platform dependent but very performant way to log info on Windows) where we can hook and see some extra details about which types are being checked with which settings, in compile phase, and whether they failed or not.

Errors like these are is the same as "Well, some error happened"

System.TypeInitializationException
The type initializer for 'Mapster.TypeAdapter`2' threw an exception.
   at lambda_method(Closure , AnnotationCommandData )
   at Utils.Mapping.DTOMap.Map[TSource,TResult](TSource inputSource) in C:\Projects\xxx\DTOMap.cs:line 42
   at UnitTests.Mappings.DTOMapTests.CheckAllMaps() in C:\Projects\xxx\Mappings\DTOMapTests.cs:line 160

System.InvalidOperationException
Instances of abstract classes cannot be created.
   at System.Runtime.CompilerServices.RuntimeHelpers._CompileMethod(IRuntimeMethodInfo method)
   at System.Reflection.Emit.DynamicMethod.CreateDelegate(Type delegateType, Object target)
   at System.Linq.Expressions.Compiler.LambdaCompiler.Compile(LambdaExpression lambda, DebugInfoGenerator debugInfoGenerator)
   at Mapster.TypeAdapterConfig.CreateMapFunction(TypeTuple tuple)
   at Mapster.TypeAdapterConfig.AddToHash(Hashtable hash, TypeTuple key, Func`2 func)
   at Mapster.TypeAdapterConfig.GetMapFunction[TSource,TDestination]()
   at Mapster.TypeAdapter`2..cctor()

Condition in custom property mapping is not working

Hi

Condition in custom property mapping is not working - or at least it is not working as expected. The documentation says:

If the condition is not met, the mapping is skipped altogether.

So as I understand it, if the condition is not met, the value in target property should not be changed. But the behavior is this:

  • If the condition is met, mapping is performed as usual.
  • If the condition is not met, the mapping is not skipped, but default value for target property type is used. This effectively nulls reference types, zeroes numbers etc.

Example

public enum TestEnum
{
    DoNotMap = 0,
    Value1 = 1,
    Value2 = 2,
}

public class TestClass
{
    public TestEnum EnumVal { get; set; }
    public string StringVal { get; set; }
}

public static void TestMapster()
{
    TypeAdapterConfig<TestClass, TestClass>.NewConfig()
        .Map(dest => dest.EnumVal, src => src.EnumVal, src => src.EnumVal != TestEnum.DoNotMap)
        .Map(dest => dest.StringVal, src => src.StringVal, src => src.StringVal != "lorem");

    var testSource = new TestClass() { EnumVal = TestEnum.DoNotMap, StringVal = "lorem" };
    var testDestination = new TestClass() { EnumVal = TestEnum.Value1, StringVal = "ipsum" };

    Console.WriteLine(testDestination.EnumVal); // Value1
    Console.WriteLine(testDestination.StringVal); // ipsum
    TypeAdapter.Adapt(testSource, testDestination);
    Console.WriteLine(testDestination.EnumVal); // DoNotMap (0) - but should be Value1
    Console.WriteLine(testDestination.StringVal?? "* NULL *"); // null - but should be "ipsum"
    Console.ReadLine();
}

Stano

ForType Settings

Hello. I have some missunderstanding. I have example code

    public class SourceClass
    {
        public string A { get; set; }
        public string B { get; set; }
        public string C { get; set; }
    }
    public class DestClass
    {
        public string A { get; set; }
        public string B { get; set; }
        public string C { get; set; }
    }
    private void MappingTest()
    {
        var sourceItem = new SourceClass()
        {
            A = "A source",
            B = "B source",
            C = "C source",
        };

        TypeAdapterConfig<SourceClass, DestClass>.NewConfig().Map(dest => dest.A,
          src => string.Format("{0} {1}", src.A, "Add something To A"));

        // This mapping gives:
        // firstResult.A =  "A source Add something To A"
        // firstResult.B = "B"
        // firstResult.C = "C"
        var firstResult = TypeAdapter.Adapt<DestClass>(sourceItem);

        // This config should extend previous config
        TypeAdapterConfig<SourceClass, DestClass>.ForType().Map(dest => dest.C,
            src => string.Format("{0} {1}", src.C, "Add something To C"));

        // This mapping also gives:
        // secondResult.A = "A source Add something To A"
        // secondResult.B = "B"
        // secondResult.C = "C"
        // But It should give
        // secondResult.A = "A source Add something To A"
        // secondResult.B = "B"
        // secondResult.C = "C Add something To C"
        var secondResult = TypeAdapter.Adapt<DestClass>(sourceItem);

    }

As you see, second ForType config is not applied. I resolved this by calling on second (ForType) config Compile() method. Is it correct?

IgnoreNullValues(true) not working with x.Adapt<TDestination>()

Hi,
I have some trouble with values initialized in destination class constructor that becomes null after mapping.
It works if I will use source.Adapt(new DestClass()); but not with source.Adapt<DestClass>();.

This is my excample code:
` public class DestClass
{
public string Title { get; set; }
public List List { get; set; }
public SubClass Sub { get; set; }

    public DestClass()
    {
        List = new List<string>();
        Sub = new SubClass();
        Title = "Hello";
    }
}

public class SourceClass
{
    public string Title { get; set; }
    public List<string> List { get; set; }
    public SubClass Sub { get; set; }
}

public class SubClass
{
    public string SubName { get; set; }
}`

And my xUnit Test:
` [Fact]
public void DoNotOverrideWithNullTest()
{
TypeAdapterConfig<SourceClass, DestClass>.NewConfig()
.IgnoreNullValues(true);

        var source = new SourceClass();
        var dest = source.Adapt<DestClass>(); // Fails
        // var dest = source.Adapt(new DestClass()); // Work fine

        Assert.Equal("Hello", dest.Title);
        Assert.NotNull(dest.Sub);
        Assert.NotNull(dest.List);
    }`

I'm using the latest version vom nuget.

Noticed an issue with require explicit mappings

I had an issue where my contract type was string[] and was mapping to IList<string>. When mapping with RequireExplicitMapping = true, this fails with a message that the mapping doesn't exist between string[] and IList<string>. I'm thinking that conversions between different enumerable types (of the same underlying type) should probably be ignored in this case. I'll try to add a test case when I get a chance if you don't have bandwidth to look into it. Don't want to lose the issue though.

Map private fields

Hi,

Is there anyway to map private fields? I'm not able to find any settings to do that

Thanks
Regards,

If only have a single constructor with parameters...map to parameters of constructor

I'm currently building a system that is very DDD oriented...as such we only want to initialize objects (even value objects) that are in the domain model (and events) via constructors. No manual assignment to properties (not even private assignment!) We don't want to initialize via mapping to properties...period. Always way to use the constructor Would be cool if:

  1. If object has a single (default) constructor with parameters, attempt to perform standard name/object mapping to the constructor parameters when creating the object.
  2. Less important: If there are multiple constructors, possibly allow a specific constructor to be chosen (attribute?) and map to that constructor (Automatically, not using ConstructWith...)

Have too many other things on my plate to implement now...but want to add a placeholder here.

Compile() errors on config.NewConfig<TimeSpan, int>()

Hello,
First thank you for the great library!

I've got the mapping config.NewConfig<TimeSpan, int>().MapWith(t => (int)t.TotalSeconds); that does work. However when I try to validate all the mappings by calling Compile(), it throws

Expression of type 'System.TimeSpan' cannot be used for parameter of type 'System.Object' of method 'Int32 ToInt32(System.Object)'

for config.NewConfig<TimeSpan, int>(). It compiles fine for the mapping in the other direction config.NewConfig<int, TimeSpan>().

So, I'm currently skipping validation of the mappings. Is it a fluke that this mapping works or does the validation have an error in it?

Mapster nuget versioning

Hi, Is this normal that Product version of mapster.dll is 2.4.2.0 and file version is still 2.1.0.0. ?
It creates a bit of confusion when being referenced in projects

<Reference Include="Mapster, Version=2.1.0.0, Culture=neutral, PublicKeyToken=2f39883af23c29a8, processorArchitecture=MSIL">
      <HintPath>..\packages\Mapster.2.4.2\lib\net45\Mapster.dll</HintPath>
      <Private>True</Private>
    </Reference>

Mapping flat to hierarchical object in v2. Potential un-flattening breaking change

Previously for mapping from flat request to more structured type I was using this configuration

TypeAdapterConfig<UserCreateRequest, NewUserDetails>.NewConfig()
  .Map(d => d.AccountLocation, s => "EU")
  .Map(d => d.UserProfile, s =>TypeAdapter.Adapt<UserCreateRequest>(s))
;

Effectively what it does is un-flattening.
Important note that now for this operation we need to specify target and source types in generic parametrization for Adapt, like this (note UserState ):

TypeAdapterConfig<UserCreateRequest, NewUserDetails>.NewConfig()
  .Map(d => d.AccountLocation, s => "AU")
  .Map(d => d.UserProfile, s =>TypeAdapter.Adapt<UserCreateRequest, UserState>(s));

Otherwise compiler will complain with this:

Error CS0854 An expression tree may not contain a call or invocation that uses optional arguments

Not a bug but worth to mention breaking change

AutoMapper 5 benchmarks

FYI the benchmark numbers for AutoMapper are pretty out of date now, the 5.0/5.1 release numbers are significantly different.

Though honestly not a huge fan of the way ExpressMapper did their benchmarks - with gigantic lists instead of calling Map over and over again. I guess both are important but I rarely get people mapping things with a million items in it, more that it's a big website and a lot of things calling Map.

Ignore nested properties

Hello!
I can't ignore nested properties, like this

TypeAdapterConfig<Student, StudentDTO>
    .NewConfig()
    .Ignore(new[] { "School.Name" });

or

TypeAdapterConfig<Student, StudentDTO>
     .NewConfig()
     .Ignore(dest => dest.School.Name);

It works only through this way??

TypeAdapterConfig<Student, StudentDTO>
    .NewConfig()

TypeAdapterConfig<School, SchoolDTO>
    .NewConfig()
    .Ignore(dest => dest.Name)

Thanks.

"Instances of abstract classes cannot be created" exception for classes with JObject properties

Hi, I'm getting a similar exception "Instances of abstract classes cannot be created." as in #52, except that I don't have nested collection of abstract types.
Instead, I have DTOs with JObject prop (and JObject has a property of JToken type and JToken is abstract).
Protected ctors and abstract classes are fine, but JObject breaks the things.

Interesting, that even if JObject is the type on both source and input DTOs (so technically it should not be mapped, just deep copied? ), mapster tries to go deeper and map all subtypes. Am I thinking about Mapster expected behaviour wrong ?

Is there any configuration setting to tell mapster not to create deep mapping substructure ? I tried to play with ConstructUsing for JObject to avoid defining it for every DTO, but that doesn't help

Here is the repro script for LINQPad (Latest Mapster 2.4.3 and latest Json.NET 9.0.1 are referenced)

void Main()
{
    string jsonText = @"
    {
      ""AA"": {
        ""Zorder"": ""9999"",
        ""PageNumber"": 1,
        ""Id"": ""f494dba7-372c-458f-942e-ecab7c938fa7"",
        ""Created"": ""2016-05-27T16:36:18.4172629+10:00"",
        ""Type"": 18,
        ""Content"": """",
        ""Geometry"": """",
        ""BlendMode"": 1
      },
      ""Id"": ""c0000000-0000-0000-0000-000000000000"",
      ""TraceId"": ""bbbbbbbb-bbbb-bb11-1111-111111111111""
    }";

    var jObjData = JObject.Parse(jsonText);

    var input = new MainSrc
    {
        BaseId = 11,
        SrcId = 1123,
        LastItem = jObjData,
    };
    //var res = jObjData.DeepClone();
    //res.GetType().Dump();
    //input.Dump();

    WebDTOMapSetup.Verify();
    var output = input.Adapt<MainSrc, MainDest>();
    output.Dump();
}


public class WebDTOMapSetup
{
    static WebDTOMapSetup()
    {
        TypeAdapterConfig<MainSrc, MainDest>.ForType();
        //TypeAdapterConfig<JObject, JObject>.ForType().ConstructUsing(f=>(JObject)f.DeepClone() as JObject)
        ;
    }
    public static void Verify()     { TypeAdapterConfig.GlobalSettings.Compile();}
}

abstract class SrcBase
{
    protected SrcBase() { }
    protected SrcBase(int baseid) { BaseId = baseid; }
    public int BaseId { get; set; }
}

abstract class DestBase
{
    protected DestBase() { }
    protected DestBase(int baseid) { BaseId = baseid; }
    public int BaseId { get; set; }
}

class MainSrc : SrcBase
{
    public int SrcId { get; set; }
    public JObject LastItem { get; set; }
}

class MainDest : DestBase
{
    public int DestId { get; set; }
    public JObject LastItem { get; set; }
}

Explicit mapping throws on mapping Enum -> String

When RequireExplicitMapping is true, the mapping complains that a map doesn't exist between the enum type and string. Had to explicitly map the property to make it work.

TypeAdapterConfig<ResponseMessage, Results.ResponseMessage>.NewConfig()
.Map(dest => dest.Type, src => src.Type.ToString());

Shouldn't need that explicit map line and it negates any perf optimizations in the mapper.

This works fine if an explicit call to compile is not conducted. But if compile is called, it complains about what should probably be an accepted primitive conversion. I messed with it a little bit but not sure the best place to implement this check.

Entity Framework + IQueryable Extensions

Hi!
(Sorry my bad english)

I'm trying to use Entity Framework with Mapster, and call Project() method. This is my scenario:

Model classes:

public class Student
{
    [Key]
    public int IDStudent { get; set; }
    public string Name { get; set; }
    public DateTime BirthDate { get; set; }
    public virtual ICollection<School> Schools { get; set; }
}

public class School
{
    [Key]
    public int IDSchool { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public virtual ICollection<Student> Students { get; set; }
}

DTO's:

public class StudentDTO
{
    [Key]
    public int IDStudent { get; set; }
    public string Name { get; set; }
    public DateTime BirthDate { get; set; }
    public ICollection<SchoolDTO> Schools { get; set; }
}

public class SchoolDTO
{
    [Key]
    public int IDSchool { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public ICollection<StudentDTO> Students { get; set; }
}

When I try

var students = context.Student.Include(p => p.Schools).Project().To<StudentDTO>().ToList();

I'm getting the following error:

LINQ to Entities does not recognize the method 'StudentDTO Invoke(Student)' method, and this method cannot be translated into a store expression.

What am I missing?

This is an amazing project! Great job, guys!

Thank you!

Exception is thrown when object with no setters is mapped to.

I have an object that is populated via the constructor, so the properties have no setters (not even private ones). Mapping to this object causes a failure. The workaround is to add private setters, but would be nice if it's not necessary to have these as it clutters the objects.

Documentation discrepancy on Global Compile

Documentation states that global compile can be performed using TypeAdapterConfig.Compile(). This method doesn't exist, but there is a TypeAdapterConfig.GlobalSettings.Compile(). Assuming this is the correct call to compile/validate globally.

Map condition for all properties of some type

Hello

Is it possible to create a map condition for all properties of given type? For example, we want to have a condition for string properties, so the values are not mapped, when source value is null or empty string (or even whitespace string). So in general, we need a map condition !string.IsNullOrWhitespace(sourceValue). But we need it for all string properties.

So is there a way writing it only once, so we do not need to make conditions for all properties?

Stano

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.