diff --git a/Extensions/Xtensive.Orm.BulkOperations/NugetContent/ReadMe.md b/Extensions/Xtensive.Orm.BulkOperations/NugetContent/ReadMe.md new file mode 100644 index 0000000000..8683627251 --- /dev/null +++ b/Extensions/Xtensive.Orm.BulkOperations/NugetContent/ReadMe.md @@ -0,0 +1,93 @@ +Xtensive.Orm.BulkOperations +=========================== + +Summary +------- +The extension provides a set of IQueryable extension methods that are translated +to server-side UPDATE or DELETE commands. + +Prerequisites +------------- +DataObjects.Net 6.0.x (http://dataobjects.net) + + +Examples of usage +----------------- + +**Example #1**. Update primitive property with a constant value: + +```csharp + session.Query.All() + .Where(a => a.Id == 1) + .Set(a => a.Count, 2) + Update(); +``` + +**Example #2** Updating persistent property with expression, computed on server: + +```csharp + session.Query.All() + .Where(a => a.Id==1) + .Set(a => a.Count, a => a.Description.Length) + .Update(); +``` + +**Example #3**. Setting a reference to an entity that is already loaded into current Session + +```csharp + // Emulating entity loading + var bar = session.Query.Single(1); + + session.Query.All() + .Where(a => a.Id == 2) + .Set(a => a.Bar, bar) + .Update(); +``` + +**Example #4**. Setting a reference to an entity that is not loaded into Session, 1st way + +```csharp + session.Query.All() + .Where(a => a.Id == 1) + .Set(a => a.Bar, a => Query.Single(1)) + .Update(); +``` + +**Example #5**. Setting a reference to an entity that is not loaded into Session, 2nd way + +```csharp + session.Query.All() + .Where(a => a.Id == 1) + .Set(a => a.Bar, a => Query.All().Single(b => b.Name == "test")) + .Update(); +``` + +**Example #6**. Constructing update expressions of the fly + +```csharp + bool condition = CheckCondition(); + var query = session.Query.All() + .Where(a => a.Id == 1) + .Set(a => a.Count, 2); + + if(condition) + query = query.Set(a => a.Name, a => a.Name + "test"); + query.Update(); +``` + +**Example #7**. Updating lots of properties at once + +```csharp + session.Query.All() + .Where(a => a.Id == 1) + Update( + a => new Bar(null) { Count = 2, Name = a.Name + "test", /*dozens of other properties...*/ }); +``` + +**Example #8**. Deleting entities + +```csharp + session.Query.All() + .Where(a => a.Id == 1) + .Delete(); +``` diff --git a/Extensions/Xtensive.Orm.BulkOperations/Readme.txt b/Extensions/Xtensive.Orm.BulkOperations/Readme.txt deleted file mode 100644 index a906cfbd92..0000000000 --- a/Extensions/Xtensive.Orm.BulkOperations/Readme.txt +++ /dev/null @@ -1,83 +0,0 @@ -=========================== -Xtensive.Orm.BulkOperations -=========================== - -Summary -------- -The extension provides a set of IQueryable extension methods that are translated -to server-side UPDATE or DELETE commands. - -Prerequisites -------------- -DataObjects.Net Core 0.1 or later (http://dataobjects.net) - -Implementation -------------- -1. Add reference to Xtensive.Orm.BulkOperations assembly - -Demo ----- -1. Update primitive property with a constant value, e.g.: - -Query.All() - .Where(a => a.Id == 1) - .Set(a => a.Count, 2) - .Update(); - -2. Updating persistent property with expression, computed on server, e.g.: - -Query.All() - .Where(a => a.Id==1) - .Set(a => a.Count, a => a.Description.Length) - .Update(); - -3. Setting a reference to an entity that is already loaded into current Session - -// Emulating entity loading -var bar = Query.Single(1); - -Query.All() - .Where(a => a.Id == 2) - .Set(a => a.Bar, bar) - .Update(); - -4. Setting a reference to an entity that is not loaded into Session, 1st way - -Query.All() - .Where(a => a.Id == 1) - .Set(a => a.Bar, a => Query.Single(1)) - .Update(); - -5. Setting a reference to an entity that is not loaded into Session, 2nd way - -Query.All() - .Where(a => a.Id == 1) - .Set(a => a.Bar, a => Query.All().Single(b => b.Name == "test")) - .Update(); - -6. Constructing update expressions of the fly - -bool condition = CheckCondition(); -var query = Query.All() - .Where(a => a.Id == 1) - .Set(a => a.Count, 2); - -if(condition) - query = query.Set(a => a.Name, a => a.Name + "test"); -query.Update(); - -7. Updating lots of properties at once - -Query.All() - .Where(a => a.Id == 1) - .Update(a => new Bar(null) { Count = 2, Name = a.Name + "test", dozens of other properties... }); - -8. Deleting entities - -Query.All() - .Where(a => a.Id == 1) - .Delete(); - -References ----------- -http://doextensions.codeplex.com \ No newline at end of file diff --git a/Extensions/Xtensive.Orm.BulkOperations/Xtensive.Orm.BulkOperations.csproj b/Extensions/Xtensive.Orm.BulkOperations/Xtensive.Orm.BulkOperations.csproj index ab231b8550..9b864b1ce6 100644 --- a/Extensions/Xtensive.Orm.BulkOperations/Xtensive.Orm.BulkOperations.csproj +++ b/Extensions/Xtensive.Orm.BulkOperations/Xtensive.Orm.BulkOperations.csproj @@ -13,8 +13,13 @@ $(ExtensionsKeyFile) true - - + + ReadMe.md + + + + . + diff --git a/Extensions/Xtensive.Orm.Localization/Readme.txt b/Extensions/Xtensive.Orm.Localization/NugetContent/ReadMe.md similarity index 63% rename from Extensions/Xtensive.Orm.Localization/Readme.txt rename to Extensions/Xtensive.Orm.Localization/NugetContent/ReadMe.md index 0021eb534a..50762e7085 100644 --- a/Extensions/Xtensive.Orm.Localization/Readme.txt +++ b/Extensions/Xtensive.Orm.Localization/NugetContent/ReadMe.md @@ -1,4 +1,3 @@ -========================= Xtensive.Orm.Localization ========================= @@ -9,35 +8,14 @@ This implies that localizable resources are a part of domain model so they are s Prerequisites ------------- -DataObjects.Net Core 0.1 or later (http://dataobjects.net) +DataObjects.Net 6.0.x or later (http://dataobjects.net) Implementation -------------- -1. Add reference to Xtensive.Orm.Localization assembly -2. Include types from Xtensive.Orm.Localization assembly into the domain: - - - - - - - - - - - - - 2.1 Optionally add default localization configuration - -
- - - - - - -3. Implement ILocalizable on your localizable entities, e.g.: +Implement ILocalizable on your localizable entities, e.g.: + +```csharp [HierarchyRoot] public class Page : Entity, ILocalizable { @@ -56,9 +34,11 @@ Implementation public Page(Session session) : base(session) {} } +``` -4. Define corresponding localizations, e.g.: +Define corresponding localizations, e.g.: +```csharp [HierarchyRoot] public class PageLocalization : Localization { @@ -68,32 +48,41 @@ Implementation public PageLocalization(Session session, CultureInfo culture, Page target) : base(session, culture, target) {} } +``` + +Examples of usage +----------------- -Demo ----- -1. Access localizable properties as regular ones, e.g.: +**Example #1**. Access localizable properties as regular ones, e.g.: +```csharp page.Title = "Welcome"; string title = page.Title; +``` -2. Mass editing of localizable properties: +**Example #2**. Mass editing of localizable properties: +```csharp var en = new CultureInfo("en-US"); var sp = new CultureInfo("es-ES"); var page = new Page(session); page.Localizations[en].Title = "Welcome"; page.Localizations[sp].Title = "Bienvenido"; +``` -3. Value of localizable properties reflects culture of the current Thread, e.g.: +**Example #3**. Value of localizable properties reflects culture of the current Thread, e.g.: +```csharp Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); string title = page.Title; // title is "Welcome" Thread.CurrentThread.CurrentCulture = new CultureInfo("es-ES"); string title = page.Title; // title is "Bienvenido" +``` -4. Instead of altering CurrentThread, instance of LocalizationScope can be used, e.g.: +**Example #4**. Instead of altering CurrentThread, instance of LocalizationScope can be used, e.g.: +```csharp using (new LocalizationScope(new CultureInfo("en-US"))) { string title = page.Title; // title is "Welcome" } @@ -101,9 +90,11 @@ Demo using (new LocalizationScope(new CultureInfo("es-ES"))) { string title = page.Title; // title is "Bienvenido" } +``` -5. LINQ queries that include localizable properties are transparently translated +**Example #5**. LINQ queries that include localizable properties are transparently translated +```csharp Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); var query = from p in session.Query.All() where p.Title=="Welcome" @@ -115,8 +106,4 @@ Demo where p.Title=="Bienvenido" select p; Assert.AreEqual(1, query.Count()); - - -References ----------- -http://doextensions.codeplex.com \ No newline at end of file +``` \ No newline at end of file diff --git a/Extensions/Xtensive.Orm.Localization/Xtensive.Orm.Localization.csproj b/Extensions/Xtensive.Orm.Localization/Xtensive.Orm.Localization.csproj index a117a119ad..9ef02202fb 100644 --- a/Extensions/Xtensive.Orm.Localization/Xtensive.Orm.Localization.csproj +++ b/Extensions/Xtensive.Orm.Localization/Xtensive.Orm.Localization.csproj @@ -12,12 +12,17 @@ true $(ExtensionsKeyFile) + + ReadMe.md + - - + + + . + diff --git a/Extensions/Xtensive.Orm.Logging.NLog/NugetContent/ReadMe.md b/Extensions/Xtensive.Orm.Logging.NLog/NugetContent/ReadMe.md new file mode 100644 index 0000000000..a1f8e892c1 --- /dev/null +++ b/Extensions/Xtensive.Orm.Logging.NLog/NugetContent/ReadMe.md @@ -0,0 +1,51 @@ +Xtensive.Orm.Logging.NLog +========================= + +Summary +------- +The extension provides integration points between DataObjects.Net internal logging system and NLog. + +Prerequisites +------------- + +DataObjects.Net 6.0.x (http://dataobjects.net) +NLog 4.5 or later (http://nlog-project.org) + +Implementation +-------------- + +Set up log provider in Xtensive.Orm configuration section + +```xml + + + + + + + +``` + +Configure NLog (https://github.com/nlog/nlog/wiki/Tutorial), e.g.: + +```xml + + + + + + + + + + + +``` + +You can choose from the following predefined internal loggers: + - "Xtensive.Orm" + - "Xtensive.Orm.Upgrade" + - "Xtensive.Orm.Building" + - "Xtensive.Orm.Core" + - "Xtensive.Orm.Sql" diff --git a/Extensions/Xtensive.Orm.Logging.NLog/Readme.txt b/Extensions/Xtensive.Orm.Logging.NLog/Readme.txt deleted file mode 100644 index 1a243baf07..0000000000 --- a/Extensions/Xtensive.Orm.Logging.NLog/Readme.txt +++ /dev/null @@ -1,51 +0,0 @@ -========================= -Xtensive.Orm.Logging.NLog -========================= - -Summary -------- -The extension provides integration points between DataObjects.Net internal logging system and NLog. - -Prerequisites -------------- -DataObjects.Net Core 0.1 or later or later (http://dataobjects.net) -NLog 4.5 or later (http://nlog-project.org) - -Implementation --------------- -1. Add reference to Xtensive.Orm.Logging.NLog assembly -2. Set up log provider in Xtensive.Orm configuration section - - - - - - - - - -3. Configure NLog (https://github.com/nlog/nlog/wiki/Tutorial), e.g.: - - - - - - - - - - - - - -You can choose from the following predefined internal loggers: - - "Xtensive.Orm" - - "Xtensive.Orm.Upgrade" - - "Xtensive.Orm.Building" - - "Xtensive.Orm.Core" - - "Xtensive.Orm.Sql" - -References ----------- -http://doextensions.codeplex.com \ No newline at end of file diff --git a/Extensions/Xtensive.Orm.Logging.NLog/Xtensive.Orm.Logging.NLog.csproj b/Extensions/Xtensive.Orm.Logging.NLog/Xtensive.Orm.Logging.NLog.csproj index 8ded369b50..9e53f46d99 100644 --- a/Extensions/Xtensive.Orm.Logging.NLog/Xtensive.Orm.Logging.NLog.csproj +++ b/Extensions/Xtensive.Orm.Logging.NLog/Xtensive.Orm.Logging.NLog.csproj @@ -12,14 +12,19 @@ true $(ExtensionsKeyFile) + + ReadMe.md + - - + + + . + diff --git a/Extensions/Xtensive.Orm.Logging.log4net/Readme.txt b/Extensions/Xtensive.Orm.Logging.log4net/NugetContent/ReadMe.md similarity index 76% rename from Extensions/Xtensive.Orm.Logging.log4net/Readme.txt rename to Extensions/Xtensive.Orm.Logging.log4net/NugetContent/ReadMe.md index e897bfada6..9fef7466c3 100644 --- a/Extensions/Xtensive.Orm.Logging.log4net/Readme.txt +++ b/Extensions/Xtensive.Orm.Logging.log4net/NugetContent/ReadMe.md @@ -1,5 +1,4 @@ -============================ -Xtensive.Orm.Logging.log4net +Xtensive.Orm.Logging.log4net ============================ Summary @@ -8,14 +7,15 @@ The extension provides integration points between DataObjects.Net internal loggi Prerequisites ------------- -DataObjects.Net Core 0.1 or later (http://dataobjects.net) -log4net 2.0.8 or later (http://logging.apache.org/log4net/) +DataObjects.Net 6.0.x (http://dataobjects.net) +log4net 2.0.10 or later (http://logging.apache.org/log4net/) Implementation -------------- -1. Add reference to Xtensive.Orm.Logging.log4net assembly -2. Set up log provider in Xtensive.Orm configuration section +Set up log provider in Xtensive.Orm configuration section + +```xml @@ -23,9 +23,11 @@ Implementation +``` -3. Configure log4net (http://logging.apache.org/log4net/release/manual/configuration.html), e.g.: +Configure log4net (http://logging.apache.org/log4net/release/manual/configuration.html), e.g.: +```xml @@ -53,6 +55,7 @@ Implementation +``` You can choose from the following predefined internal loggers: - "Xtensive.Orm" @@ -60,7 +63,3 @@ You can choose from the following predefined internal loggers: - "Xtensive.Orm.Building" - "Xtensive.Orm.Core" - "Xtensive.Orm.Sql" - -References ----------- -http://doextensions.codeplex.com \ No newline at end of file diff --git a/Extensions/Xtensive.Orm.Logging.log4net/Xtensive.Orm.Logging.log4net.csproj b/Extensions/Xtensive.Orm.Logging.log4net/Xtensive.Orm.Logging.log4net.csproj index 8760125022..a9065ef23a 100644 --- a/Extensions/Xtensive.Orm.Logging.log4net/Xtensive.Orm.Logging.log4net.csproj +++ b/Extensions/Xtensive.Orm.Logging.log4net/Xtensive.Orm.Logging.log4net.csproj @@ -12,14 +12,19 @@ true $(ExtensionsKeyFile) + + ReadMe.md + - - + + + . + diff --git a/Extensions/Xtensive.Orm.Reprocessing/Readme.txt b/Extensions/Xtensive.Orm.Reprocessing/NugetContent/ReadMe.md similarity index 61% rename from Extensions/Xtensive.Orm.Reprocessing/Readme.txt rename to Extensions/Xtensive.Orm.Reprocessing/NugetContent/ReadMe.md index 3fa77cb955..49f73218bf 100644 --- a/Extensions/Xtensive.Orm.Reprocessing/Readme.txt +++ b/Extensions/Xtensive.Orm.Reprocessing/NugetContent/ReadMe.md @@ -1,4 +1,3 @@ -========================= Xtensive.Orm.Reprocessing ========================= @@ -9,43 +8,44 @@ should represent a separate block of logic, usually a delegate of a method and b Prerequisites ------------- -DataObjects.Net Core 0.1 or later (http://dataobjects.net) - -Implementation --------------- -1. Add reference to Xtensive.Orm.Reprocessing assembly +DataObjects.Net 6.0.x (http://dataobjects.net) -Demo ----- -1. Simple reprocessible operation looks like this: +Examples of usage +----------------- +**Examples #1**. Simple reprocessible operation looks like this: -Domain.Execute(session => - { +```csharp + Domain.Execute(session => { // Task logic }); +``` -2. There are 3 strategies that can be used for task execution: -- HandleReprocessibleException strategy +**Expample #2**. Usage of built-in reprocessing strategies. + +There are 3 strategies that can be used for task execution: +- **HandleReprocessibleException** strategy The strategy catches all reprocessible expections (deadlock and transaction serialization exceptions) and makes another attempt to execute the task -- HandleUniqueConstraintViolation strategy +- **HandleUniqueConstraintViolation** strategy The same as previous one but also catches unique constraint violation exception -- NoReprocess strategy +- **NoReprocess** strategy No reprocessing is provided To indicate that a particular strategy should be used, use the following syntax: -Domain.WithStrategy(new HandleReprocessExceptionStrategy()) - .Execute(session => - { - // Task logic - }); +```csharp + Domain.WithStrategy(new HandleReprocessExceptionStrategy()) + .Execute(session => { + // Task logic + }); +``` -3. To omit setting up the strategy each time consider configuring it in +**Expample #3**. Confugure reprocessing in configuration file. To omit setting up the strategy each time consider configuring it in application configuration file, e.g.: +```xml - ... +
@@ -54,10 +54,7 @@ application configuration file, e.g.: defaultTransactionOpenMode="New" defaultExecuteStrategy="Xtensive.Orm.Reprocessing.HandleReprocessableExceptionStrategy, Xtensive.Orm.Reprocessing"> +``` Having that done, in scenarios with no strategy specified, the extension will automatically use -the strategy from the configuration. - -References ----------- -http://doextensions.codeplex.com \ No newline at end of file +the strategy from the configuration. \ No newline at end of file diff --git a/Extensions/Xtensive.Orm.Reprocessing/Xtensive.Orm.Reprocessing.csproj b/Extensions/Xtensive.Orm.Reprocessing/Xtensive.Orm.Reprocessing.csproj index df27502453..bb5f4853b3 100644 --- a/Extensions/Xtensive.Orm.Reprocessing/Xtensive.Orm.Reprocessing.csproj +++ b/Extensions/Xtensive.Orm.Reprocessing/Xtensive.Orm.Reprocessing.csproj @@ -12,11 +12,16 @@ true $(ExtensionsKeyFile) + + ReadMe.md + - - + + + . + diff --git a/Extensions/Xtensive.Orm.Security/Readme.txt b/Extensions/Xtensive.Orm.Security/NugetContent/ReadMe.md similarity index 69% rename from Extensions/Xtensive.Orm.Security/Readme.txt rename to Extensions/Xtensive.Orm.Security/NugetContent/ReadMe.md index edad87223a..9cb9ae40e1 100644 --- a/Extensions/Xtensive.Orm.Security/Readme.txt +++ b/Extensions/Xtensive.Orm.Security/NugetContent/ReadMe.md @@ -1,4 +1,3 @@ -===================== Xtensive.Orm.Security ===================== @@ -9,13 +8,14 @@ There are 2 main parts that can also be used separately: authentication services Prerequisites ------------- -DataObjects.Net 0.1 or later (http://dataobjects.net) +DataObjects.Net 6.0.x or later (http://dataobjects.net) + +How to use +---------- -Implementation --------------- -1. Add reference to Xtensive.Orm.Security assembly -2. Include types from Xtensive.Orm.Security assembly into the domain: +Include types from Xtensive.Orm.Security assembly into the domain: +```xml @@ -26,23 +26,29 @@ Implementation +``` -3. If you are planning to use one of authentication services add +If you are planning to use one of authentication services add +```xml
+``` and set up the desired hashing service: +```xml +``` -Demo ----- +Examples +-------- -1. Define a class that inherits GenericPrincipal class that will describe your users, e.g.: +**Example #1**. Definition of a class that inherits GenericPrincipal class that will describe your users, e.g.: +```csharp [HierarchyRoot] public class User : GenericPrincipal { @@ -57,11 +63,16 @@ Demo ... - public User(Session session) : base(session) {} + public User(Session session) + : base(session) + { + } } +``` -2. Having the User class defined, it can be used for user creation and authentication. +**Example #2**. Having the User class defined above, it can be used for user creation and authentication. +```csharp // Creating a user using (var session = Domain.OpenSession()) { using (var transaction = session.OpenTransaction()) { @@ -79,9 +90,11 @@ Demo transaction.Complete(); } } +``` -3. Define a hierarchy of roles. A role is a set of permissions for a job fuction within a company, e.g.: +**Example #3**. Definition of a hierarchy of roles for users. A role is a set of permissions for a job fuction within a company, e.g.: +``` EmployeeRole | |- StockManagerRole @@ -91,7 +104,11 @@ EmployeeRole |- SalesManagerRole | |- SalesPresidentRole +``` +The role tree above can be represented like following: + +```csharp // This is base role for all employees [HierarchyRoot(InheritanceSchema = InheritanceSchema.SingleTable)] public abstract class EmployeeRole : Role @@ -126,7 +143,59 @@ EmployeeRole : base(session) {} } - // Create instances of roles on first domain initialization + public class SalesRepresentativeRole : EmployeeRole + { + protected override void RegisterPermissions() + { + // Sales manager inherits Employee permissions + base.RegisterPermissions(); + + // All sales representative can read customer + RegisterPermission(new Permission()); + // All sales representative can read orders + RegisterPermission(new Permission()); + } + + protected EmployeeRole(Session session) + : base(session) {} + } + + public class SalesManagerRole : SalesRepresentativeRole + { + protected override void RegisterPermissions() + { + // Sales manager inherits SalesRepresentativeRole permissions + base.RegisterPermissions(); + + // Sales managers can read and write orders + RegisterPermission(new Permission(canWrite:true)); + } + + protected SalesManagerRole(Session session) + : base(session) {} + } + + public class SalesPresidentRole : SalesRepresentativeRole + { + protected override void RegisterPermissions() + { + // Sales manager inherits SalesRepresentativeRole permissions + base.RegisterPermissions(); + + // Sales president can read and write customers + RegisterPermission(new Permission(canWrite:true)); + // Sales president can read and write orders + RegisterPermission(new Permission(canWrite:true)); + } + + protected SalesManagerRole(Session session) + : base(session) {} + } +``` + +The roles should be intitalized on first domain build for being able to use them further, e.g: + +```csharp using (var session = Domain.OpenSession()) { using (var transaction = session.OpenTransaction()) { new SalesRepresentativeRole(session); @@ -136,9 +205,11 @@ EmployeeRole transaction.Complete(); } } +``` -4. Members of staff are assigned particular roles, e.g.: +**Example #4**. Assigning one of roles to a user. +```csharp using (var session = Domain.OpenSession()) { using (var transaction = session.OpenTransaction()) { var stockManagerRole = session.Query.All().Single(); @@ -149,15 +220,19 @@ EmployeeRole transaction.Complete(); } } +``` -5. Checking whether a user has the required role +**Example #5**. Checking whether a user has the required role +```csharp user.IsInRole("StockManagerRole"); // or user.Roles.Contains(stockManagerRole); +``` -6. Session impersonation +**Example #6**. Session impersonation +```csharp using (var imContext = session.Impersonate(user)) { // inside the region the session is impersonated with the specified // principal and set of their roles and permissions @@ -173,10 +248,12 @@ EmployeeRole if (p != null && p.CanRead) // allow doing some stuff } +``` To end the impersonation call ImpersonationContext.Undo() or Dispose() method. Impersonation contexts can be nested, e.g.: +```csharp using (var userContext = session.Impersonate(user)) { // do some user-related stuff @@ -187,10 +264,12 @@ Impersonation contexts can be nested, e.g.: // we are still in user impersonation context } // no context here +``` -7. Secure (restrictive) queries +**Example #7**. Secure (restrictive) queries. A role may set up a condition that will be automatically added to any query and limits the query results, e.g.: +```csharp public class AutomobileManagerRole : EmployeeRole { private static IQueryable GetCustomers(ImpersonationContext context, QueryEndpoint query) @@ -210,10 +289,12 @@ A role may set up a condition that will be automatically added to any query and public AutomobileManagerRole(Session session) : base(session) {} } +``` Now all employees that have AutomobileManagerRole will read customers that have IsAutomobileIndustry property set to true, e.g.: +```csharp using (var session = Domain.OpenSession()) { using (var transaction = session.OpenTransaction()) { var automobileManagerRole = session.Query.All().Single(); @@ -230,7 +311,4 @@ customers that have IsAutomobileIndustry property set to true, e.g.: transaction.Complete(); } } - -References ----------- -http://doextensions.codeplex.com \ No newline at end of file +``` \ No newline at end of file diff --git a/Extensions/Xtensive.Orm.Security/Xtensive.Orm.Security.csproj b/Extensions/Xtensive.Orm.Security/Xtensive.Orm.Security.csproj index 9107b41055..5d25cf0853 100644 --- a/Extensions/Xtensive.Orm.Security/Xtensive.Orm.Security.csproj +++ b/Extensions/Xtensive.Orm.Security/Xtensive.Orm.Security.csproj @@ -12,6 +12,9 @@ true $(ExtensionsKeyFile) + + ReadMe.md + @@ -19,8 +22,10 @@ - - + + + . + diff --git a/Extensions/Xtensive.Orm.Tracking/Readme.txt b/Extensions/Xtensive.Orm.Tracking/NugetContent/ReadMe.md similarity index 52% rename from Extensions/Xtensive.Orm.Tracking/Readme.txt rename to Extensions/Xtensive.Orm.Tracking/NugetContent/ReadMe.md index db1aaf1550..4bd430c76c 100644 --- a/Extensions/Xtensive.Orm.Tracking/Readme.txt +++ b/Extensions/Xtensive.Orm.Tracking/NugetContent/ReadMe.md @@ -12,9 +12,10 @@ DataObjects.Net Core 0.1 or later (http://dataobjects.net) Implementation -------------- -1. Add reference to Xtensive.Orm.Tracking assembly -2. Include types from Xtensive.Orm.Tracking assembly into the domain: +1. Include types from Xtensive.Orm.Tracking assembly into the domain: + +```xml @@ -25,17 +26,25 @@ Implementation -3. To track changes on Session level obtain an instance of ISessionTrackingMonitor through Session.Services.Get() method To track changes on Domain level (from all sessions) obtain an instance of IDomainTrackingMonitor through Domain.Services.Get() method -4. Subscribe to TrackingCompleted event. After each tracked transaction is committed you receive the TrackingCompletedEventArgs object. -5. TrackingCompletedEventArgs.Changes contains a collection of ITrackingItem objects, each of them represents a set of changes that occured to an Entity within the transaction committed. +``` + +2. To track changes on ```Session``` level obtain an instance of ```ISessionTrackingMonitor``` through ```Session.Services.Get()``` method; to track changes on ```Domain``` level (from all sessions) obtain an instance of ```IDomainTrackingMonitor``` through ```Domain.Services.Get()``` method +3. Subscribe to ```TrackingCompleted``` event. After each tracked transaction is committed you receive the ```TrackingCompletedEventArgs``` object. +4. ```TrackingCompletedEventArgs.Changes``` contains a collection of ```ITrackingItem``` objects, each of them represents a set of changes that occured to an ```Entity``` within the transaction committed. Demo ---- -1. Subscribe to ISessionTrackingMonitor/IDomainTrackingMonitor TrackingCompleted event + +First, subscribe to the ```TrackingCompleted``` event of ```ISessionTrackingMonitor``` / ```IDomainTrackingMonitor``` + +```csharp var monitor = Domain.Services.Get(); monitor.TrackingCompleted += TrackingCompletedListener; +``` -2. Do some changes to persistent entities +Then, do some changes to persistent entities + +```csharp using (var session = Domain.OpenSession()) { using (var t = session.OpenTransaction()) { var e = new MyEntity(session); @@ -43,8 +52,11 @@ using (var session = Domain.OpenSession()) { t.Complete(); } } +``` + +And handle ```TrackingCompleted``` event call and do whatever you want with tracked changes. -3. Handle TrackingCompleted event call and do whatever you want with tracked changes. +```csharp private void TrackingCompletedListener(object sender, TrackingCompletedEventArgs e) { foreach (var change in e.Changes) { @@ -58,7 +70,4 @@ private void TrackingCompletedListener(object sender, TrackingCompletedEventArgs } } } - -References ----------- -http://doextensions.codeplex.com \ No newline at end of file +``` diff --git a/Extensions/Xtensive.Orm.Tracking/Xtensive.Orm.Tracking.csproj b/Extensions/Xtensive.Orm.Tracking/Xtensive.Orm.Tracking.csproj index ae6f2f08b0..b51054b325 100644 --- a/Extensions/Xtensive.Orm.Tracking/Xtensive.Orm.Tracking.csproj +++ b/Extensions/Xtensive.Orm.Tracking/Xtensive.Orm.Tracking.csproj @@ -12,13 +12,18 @@ true $(ExtensionsKeyFile) + + ReadMe.md + - - + + + . + \ No newline at end of file diff --git a/Extensions/Xtensive.Orm.Web/Readme.txt b/Extensions/Xtensive.Orm.Web/NugetContent/ReadMe.md similarity index 96% rename from Extensions/Xtensive.Orm.Web/Readme.txt rename to Extensions/Xtensive.Orm.Web/NugetContent/ReadMe.md index 68b81ecd7d..e661a2da0c 100644 --- a/Extensions/Xtensive.Orm.Web/Readme.txt +++ b/Extensions/Xtensive.Orm.Web/NugetContent/ReadMe.md @@ -1,5 +1,4 @@ -================ -Xtensive.Orm.Web +Xtensive.Orm.Web ================ Summary @@ -25,12 +24,13 @@ in your code (directly or indirectly). So e.g. requests to static web pages won' Prerequisites ------------- -DataObjects.Net Core 0.1 or later (http://dataobjects.net) +DataObjects.Net 6.0.x or later (http://dataobjects.net) Implementation -------------- To start using SessionManager it should be added to ASP.NET Middleware pipeline in Startup class like in example below +```csharp public class Startup { public Startup(IConfiguration configuration) @@ -52,10 +52,10 @@ public class Startup // Add session manager to the pipeline app.UseSessionManager(); - + // Configure parts of the pipeline which are after SessionManager. // These parts will work with SessionManager. - + // For instance, MVC controllers will be able to query data using DataObjects.Net app.UseMvc(routes => { @@ -64,4 +64,5 @@ public class Startup template: "{controller=Home}/{action=Index}/{id?}"); }); } -} \ No newline at end of file +} +``` \ No newline at end of file diff --git a/Extensions/Xtensive.Orm.Web/Xtensive.Orm.Web.csproj b/Extensions/Xtensive.Orm.Web/Xtensive.Orm.Web.csproj index 19b99c8579..48fadb1226 100644 --- a/Extensions/Xtensive.Orm.Web/Xtensive.Orm.Web.csproj +++ b/Extensions/Xtensive.Orm.Web/Xtensive.Orm.Web.csproj @@ -12,8 +12,13 @@ true $(ExtensionsKeyFile) - - + + ReadMe.md + + + + . + diff --git a/Orm/Xtensive.Orm.Firebird/Xtensive.Orm.Firebird.csproj b/Orm/Xtensive.Orm.Firebird/Xtensive.Orm.Firebird.csproj index 51b080e670..2a75cae6b3 100644 --- a/Orm/Xtensive.Orm.Firebird/Xtensive.Orm.Firebird.csproj +++ b/Orm/Xtensive.Orm.Firebird/Xtensive.Orm.Firebird.csproj @@ -15,6 +15,9 @@ true 2 + + ReadMe.md + . diff --git a/Orm/Xtensive.Orm.MySql/Xtensive.Orm.MySql.csproj b/Orm/Xtensive.Orm.MySql/Xtensive.Orm.MySql.csproj index 2c1e4cdf97..c028ffac50 100644 --- a/Orm/Xtensive.Orm.MySql/Xtensive.Orm.MySql.csproj +++ b/Orm/Xtensive.Orm.MySql/Xtensive.Orm.MySql.csproj @@ -15,6 +15,9 @@ true 2 + + ReadMe.md + . diff --git a/Orm/Xtensive.Orm.Oracle/Xtensive.Orm.Oracle.csproj b/Orm/Xtensive.Orm.Oracle/Xtensive.Orm.Oracle.csproj index 63c345b709..76ae2cfbb1 100644 --- a/Orm/Xtensive.Orm.Oracle/Xtensive.Orm.Oracle.csproj +++ b/Orm/Xtensive.Orm.Oracle/Xtensive.Orm.Oracle.csproj @@ -15,6 +15,9 @@ true 2 + + ReadMe.md + . diff --git a/Orm/Xtensive.Orm.PostgreSql/Xtensive.Orm.PostgreSql.csproj b/Orm/Xtensive.Orm.PostgreSql/Xtensive.Orm.PostgreSql.csproj index 20246b7908..42edabd622 100644 --- a/Orm/Xtensive.Orm.PostgreSql/Xtensive.Orm.PostgreSql.csproj +++ b/Orm/Xtensive.Orm.PostgreSql/Xtensive.Orm.PostgreSql.csproj @@ -21,6 +21,9 @@ TRACE;NETSTANDARD + + ReadMe.md + . diff --git a/Orm/Xtensive.Orm.SqlServer/Xtensive.Orm.SqlServer.csproj b/Orm/Xtensive.Orm.SqlServer/Xtensive.Orm.SqlServer.csproj index 632b997841..2644a90433 100644 --- a/Orm/Xtensive.Orm.SqlServer/Xtensive.Orm.SqlServer.csproj +++ b/Orm/Xtensive.Orm.SqlServer/Xtensive.Orm.SqlServer.csproj @@ -15,6 +15,9 @@ true 2 + + ReadMe.md + . diff --git a/Orm/Xtensive.Orm.Sqlite/Xtensive.Orm.Sqlite.csproj b/Orm/Xtensive.Orm.Sqlite/Xtensive.Orm.Sqlite.csproj index 02e944f220..72aba47077 100644 --- a/Orm/Xtensive.Orm.Sqlite/Xtensive.Orm.Sqlite.csproj +++ b/Orm/Xtensive.Orm.Sqlite/Xtensive.Orm.Sqlite.csproj @@ -15,6 +15,9 @@ true 2 + + ReadMe.md + . diff --git a/Orm/Xtensive.Orm/Xtensive.Orm.csproj b/Orm/Xtensive.Orm/Xtensive.Orm.csproj index ebc0ee9b53..7c42ab43f7 100644 --- a/Orm/Xtensive.Orm/Xtensive.Orm.csproj +++ b/Orm/Xtensive.Orm/Xtensive.Orm.csproj @@ -25,6 +25,9 @@ true portable + + ReadMe.md +