{"id":19992860,"url":"https://github.com/ClockGet/AutoCopy","last_synced_at":"2025-05-04T12:30:27.223Z","repository":{"id":125407769,"uuid":"104035120","full_name":"ClockGet/AutoCopy","owner":"ClockGet","description":"A automatic object-object copyer","archived":false,"fork":false,"pushed_at":"2018-02-09T14:24:05.000Z","size":109,"stargazers_count":84,"open_issues_count":0,"forks_count":2,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-11-13T04:55:44.580Z","etag":null,"topics":["autocopy","automapper","func-delegate","lambdaexpression","reflection"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ClockGet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-09-19T06:25:25.000Z","updated_at":"2023-03-09T04:28:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"42825fcc-47bf-4ec3-80c8-9d0cee62918c","html_url":"https://github.com/ClockGet/AutoCopy","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClockGet%2FAutoCopy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClockGet%2FAutoCopy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClockGet%2FAutoCopy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClockGet%2FAutoCopy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ClockGet","download_url":"https://codeload.github.com/ClockGet/AutoCopy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252333946,"owners_count":21731301,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["autocopy","automapper","func-delegate","lambdaexpression","reflection"],"created_at":"2024-11-13T04:52:21.330Z","updated_at":"2025-05-04T12:30:27.211Z","avatar_url":"https://github.com/ClockGet.png","language":"C#","funding_links":[],"categories":["C\\#"],"sub_categories":[],"readme":"## AutoCopy\n\nAutoCopy is a tool that reduces development time and helps programmers get out of some heavy human coding, which is inspired by **[AutoMapper](https://github.com/AutoMapper/AutoMapper \"AutoMapper\")**.\n\n## Document\n\n[Chinese](README_CN.md)\n\n## Dependencies\n\n* **[Mono.Reflection.dll](https://github.com/jbevain/mono.reflection \"Mono.Reflection\")**\n* **[DelegateDecompiler.dll](https://github.com/hazzik/DelegateDecompiler \"DelegateDecompiler\")**\n\n## Attribute\n\n1. Fast execution\n2. Based on the abstract class **TargetExpressionProviderBase** can be any extension\n3. Support automatic / manual type conversion\n4. Support for multiple instances of AutoCopy nesting\n\n## Benchmark\n\niterations:100,000\n\n| Action | mean time(ms)\n---|---\nhand map | 4.267375\nAutoCopy | 4.18163333333333\nAutoMapper | 42.4985\n\niterations:1,000,000\n\n| Action | mean time(ms)\n---|---\nhand map | 30.884225\nAutoCopy | 38.647675\nAutoMapper | 322.8877\n\niterations:10,000,000\n\n| Action | mean time(ms)\n---|---\nhand map | 440.14825\nAutoCopy | 459.17575\nAutoMapper | 3895.974725\n\nBenchmark code see [here](/Console.Test/Program.cs)\n\n## Example\n\n### 1 Same type of object copyed\n\n```csharp\n\n    public class Address\n    {\n        public string ZipCode { get; set; }\n    }\n\n    var autoCopy = AutoCopy.CreateMap\u003cAddress, Address\u003e();\n\n    autoCopy.Register();\n\n    Address a=new Address { ZipCode=\"1234567890\"; };\n\n    Address b=autoCopy.Map(a);\n\n```\n\n### 2 Different type of object copyed\n\n```csharp\n\n    public class Address\n    {\n        public string ZipCode { get; set; }\n    }\n\n    public class Telephone\n    {\n        public string Number { get; set; }\n    }\n\n    public class Customer\n    {\n        public Address Address { get; set; }\n        public Telephone Phone { get; set; }\n        public string Memo { get; set; }\n    }\n\n    public class CustomerInfo\n    {\n        public string zipCode { get; set; }\n        public string PhoneNumber { get; set; }\n        public string Memo { get; set; }\n    }\n\n    var autoCopy = AutoCopy.CreateMap\u003cCustomer, CustomerInfo\u003e();\n\n    autoCopy\n        .ForMember(p =\u003e p.zipCode, opt =\u003e opt.MapFrom(p =\u003e p.Address.ZipCode))\n        .ForMember(p =\u003e p.PhoneNumber, opt =\u003e opt.MapFrom(p =\u003e p.Phone.Number));\n\n    autoCopy.Register();\n\n    Customer customer = new Customer();\n    \n    customer.Address = new Address { ZipCode = \"1234567890\" };\n    \n    customer.Phone = new Telephone { Number = \"17791704580\" };\n    \n    customer.Memo = \"Test\";\n    \n    CustomerInfo info = autoCopy.Map(customer);\n\n```\n\n### 3 Multiple AutoCopy instances nested\n\n```csharp\n\n    public class Data\n    {\n        public int width { get; set; }\n        public int height { get; set; }\n        public string ua { get; set; }\n        public string ip { get; set; }\n        public string imei { get; set; }\n        public string android_id { get; set; }\n        public string make { get; set; }\n        public string model { get; set; }\n        public string os { get; set; }\n        public string osv { get; set; }\n        public int connectionType { get; set; }\n        public int deviceType { get; set; }\n        public string mac { get; set; }\n        public int screenWidth { get; set; }\n        public int screenHeight { get; set; }\n        public string appName { get; set; }\n        public int ppi { get; set; }\n        public string dpidsha1 { get; set; }\n        public string plmn { get; set; }\n        public string orientation { get; set; }\n        public int pos { get; set; }\n        public bool instl { get; set; }\n        public string ver { get; set; }\n        public string bundle { get; set; }\n        public Ext ext { get; set; }\n    }\n    public class Ext\n    {\n        public int ID { get; set; }\n    }\n\n    string surl = \"id=10010\u0026width=10\u0026height=10\u0026ua=ua\u0026ip=127.0.0.1\u0026imei=00000000000000\u0026android_id=A00000000000000\u0026make=1111111111\u0026model=XXX\u0026os=android\u0026osv=4.0.1\u0026connectionType=1\u0026deviceType=1\u0026mac=0.0.0.0.0.0.0\u0026screenWidth=100\u0026screenHeight=100\u0026appName=test\u0026ppi=600\u0026dpidsha1=dpidsha1\u0026plmn=1\u0026orientation=1\u0026pos=1\u0026instl=true\u0026ver=1.0.0\u0026bundle=bundle\";\n\n    HttpQueryCollection collection = new HttpQueryCollection(surl, false);\n\n    var ac = AutoCopy.CreateMap\u003cNameValueCollection, Ext\u003e();\n\n    ac.Provider= new HttpRequestParamsExpressionProvider(typeof(NameValueCollection));\n\n    var autoCopy = AutoCopy.CreateMap\u003cNameValueCollection, Data\u003e();\n\n    autoCopy.ForMember(p =\u003e p.ext, opt =\u003e opt.MapFrom(p=\u003eac.Map(p)));\n\n    autoCopy.Provider = new HttpRequestParamsExpressionProvider(typeof(NameValueCollection));\n\n    autoCopy.Register();\n\n    Data data=autoCopy.Map(collection);\n\n```\n## Type Convert\n### Automatic conversion\nThe TryConvert method of the internal class [TypeConverter](/AutoCopyLib/TypeConverter.cs) performs automatic conversion of the type in the following order：\n\n1. Whether there is a explicit operator\n2. Whether there is a implicit operator\n3. Whether it is a subclass\n4. Whether there is the Convert.ToXXX method\n5. Whether there is the TryParse method on the target type\n6. Call [Convert.ChangeType](https://msdn.microsoft.com/en-us/library/system.convert.changetype(v=vs.110).aspx \"Convert.ChangeType\") method\n### Manual conversion\n\nType conversions are registered by calling the **ForTypeConvert\u003cT1, T2\u003e** method of the **AutoCopy\u003cT, D\u003e** instance.\n\n## Explanation of Parameter in [TryGetExpression](/AutoCopyLib/TargetExpressionProviderBase.cs) method\n\nWith AutoCopy\u003cT1, T2\u003e, assume T1 is the source type and T2 is the destination type\n\n| | Parameter Name | Description\n---|---|---\n1 | name | destination property name\n2 | parameter | Expression of source parameter Expression\n3 | destType | destination type\n4 | exp | the final Expression\n5 | variable | variables\n6 | test | test Expression\n7 | ifTrue | Whether need to test or not; If the value is true, then only the test Expression executed return true can exp Expression will be called\n\n## ChangeLog\n2017-12-05 Add a demo which show the DataRow class convert to entity class  \n2017-12-12 Adjust the order of parameters in AutoCopy\u003c,\u003e and fixed the parameter type bug in Option.ResolveUsing  \n2017-12-26 Add the CopyMapAttribute attribute to support alias mapping of destination type property  \n2017-12-27 Add the CopyRequiredAttribute attribute to support the detection of the destination type property map value is required to be empty **[Need further testing]**  \n2017-12-28 Get a new LambdaExpression from the Decompiler function when another AutoCopy instance is called in the Option.MapFrom function  \n2018-01-12 Overload the Option.MapForm function, add a string parameter indicating the target's property name or mapping name  \n2018-02-09 fixed bug: When the CopyRequired attribute is applied to a property that requires nested mapping of an AutoCopy instance, called the Visit function of ConditionFalseRewriter class would cause error  \n## Warning\n\nSince AutoCopy uses reflection at runtime to analysis the properties of classes by calling **Register** methods automatically, bugs may occur if the source code is obfuscated.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FClockGet%2FAutoCopy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FClockGet%2FAutoCopy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FClockGet%2FAutoCopy/lists"}