Skip to content

Allow disabling scan for data annotations attributes #4614

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
May 15, 2025
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Source/Csla.Windows.Tests/test.runsettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<RunConfiguration>
<MaxCpuCount>1</MaxCpuCount>
</RunConfiguration>
</RunSettings>
3 changes: 2 additions & 1 deletion Source/Csla.test/Basic/BasicTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,8 @@ public void DeletedListTestWithCancel()
public void SuppressListChangedEventsDoNotRaiseCollectionChanged()
{
bool changed = false;
var obj = new RootList();
var portal = _testDIContext.CreateDataPortal<RootList>();
var obj = portal.Create();
obj.ListChanged += (_, _) =>
{
changed = true;
Expand Down
3 changes: 2 additions & 1 deletion Source/Csla.test/Basic/CollectionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ public void SetLast()
[TestMethod]
public void RootListGetRuleDescriptions()
{
RootList list = new RootList();
var portal = _testDIContext.CreateDataPortal<RootList>();
var list = portal.Create();
RootListChild child = list.AddNew();
string[] rules = child.GetRuleDescriptions();
}
Expand Down
15 changes: 8 additions & 7 deletions Source/Csla.test/Basic/RootList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,20 @@ namespace Csla.Test.Basic
[Serializable]
public class RootList : BusinessBindingListBase<RootList, RootListChild>
{
public RootList()
{
AllowEdit = true;
AllowNew = true;
AllowRemove = true;
}

protected override object AddNewCore()
{
RootListChild child = new RootListChild();
Add(child);
return child;
}

[Create]
private void Create()
{
AllowNew = true;
AllowEdit = true;
AllowRemove = true;
}
}

[Serializable]
Expand Down
90 changes: 90 additions & 0 deletions Source/Csla.test/BizRules/BusinessRuleTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
//-----------------------------------------------------------------------
// <copyright file="BusinessRuleTests.cs" company="Marimer LLC">
// Copyright (c) Marimer LLC. All rights reserved.
// Website: https://cslanet.com
// </copyright>
// <summary>no summary</summary>
//-----------------------------------------------------------------------
using System.ComponentModel.DataAnnotations;
using Csla.Configuration;
using Csla.TestHelpers;
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Csla.Test.BizRules
{
[TestClass]
public class BusinessRuleTests
{
private static TestDIContext _testDIContext;

[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
_testDIContext = TestDIContextFactory.CreateDefaultContext();
}

[TestInitialize]
public void Initialize()
{
TestResults.Reinitialise();
}

[TestMethod]
public void DefaultDataAnnotationsScan()
{
var portal = _testDIContext.ServiceProvider.GetRequiredService<IDataPortal<TestBusinessRule>>();
var obj = portal.Create();
obj.Name = "";
obj.IsValid.Should().BeFalse();
}

[TestMethod]
public void DisableDataAnnotationsScan()
{
var options = _testDIContext.ServiceProvider.GetRequiredService<CslaOptions>();
options.ScanForDataAnnotations(false);

// use different type to avoid caching
var portal = _testDIContext.ServiceProvider.GetRequiredService<IDataPortal<TestBusinessRule2>>();
var obj = portal.Create();
obj.Name = "";
obj.IsValid.Should().BeTrue();
}
}

public class TestBusinessRule : BusinessBase<TestBusinessRule>
{
public static readonly PropertyInfo<string> NameProperty = RegisterProperty<string>(nameof(Name));
[Required]
public string Name
{
get => GetProperty(NameProperty);
set => SetProperty(NameProperty, value);
}

[Create]
private void Create()
{
BusinessRules.CheckRules();
}
}

public class TestBusinessRule2 : BusinessBase<TestBusinessRule2>
{
public static readonly PropertyInfo<string> NameProperty = RegisterProperty<string>(nameof(Name));
[Required]
public string Name
{
get => GetProperty(NameProperty);
set => SetProperty(NameProperty, value);
}

[Create]
private void Create()
{
BusinessRules.CheckRules();
}
}
}
48 changes: 43 additions & 5 deletions Source/Csla.test/ChildrenByInterface/ChildInterfaceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,41 @@
// <summary>no summary</summary>
//-----------------------------------------------------------------------

using Csla.TestHelpers;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Csla.Test.ChildrenByInterface
{
[TestClass]
public class ChildInterfaceTests
{
private static TestDIContext _testDIContext;

[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
_testDIContext = TestDIContextFactory.CreateDefaultContext();
}

[TestInitialize]
public void Initialize()
{
TestResults.Reinitialise();
}

[TestMethod]
public void AddItems()
{
ItemList list =
var portal = _testDIContext.CreateDataPortal<ItemList>();
var child1Portal = _testDIContext.CreateDataPortal<Item1>();
var child2Portal = _testDIContext.CreateDataPortal<Item2>();
var list = portal.Create();
list.AddRange(
[
new Item1(),
new Item2()
child1Portal.Create(),
child2Portal.Create()

];
]);

Assert.IsTrue(list[0] is Item1, "First element should be Item1");
Assert.IsTrue(list[1] is Item2, "Second element should be Item2");
Expand All @@ -42,6 +61,11 @@ protected override object GetIdValue()
{
return 0;
}

[Create]
private void Create()
{
}
}

[Serializable]
Expand All @@ -56,8 +80,22 @@ protected override object GetIdValue()
{
return 0;
}

[Create]
private void Create()
{
}
}

[Serializable]
public class ItemList : BusinessBindingListBase<ItemList, IItem>;
public class ItemList : BusinessBindingListBase<ItemList, IItem>
{
[Create]
private void Create()
{
AllowNew = true;
AllowEdit = true;
AllowRemove = true;
}
}
}
7 changes: 2 additions & 5 deletions Source/Csla.test/Nullable/NullableObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,7 @@ public static void DeleteNullableObject(string name, IDataPortal<NullableObject>
dataPortal.Delete(new Criteria(name));
}

public NullableObject()
{
AddBusinessRules();
}

[Create]
private void DataPortal_Create(object criteria)
{
Criteria crit = (Criteria)(criteria);
Expand All @@ -86,6 +82,7 @@ private void DataPortal_Create(object criteria)
TestResults.Add("NullableObject", "Created");
}

[Fetch]
protected void DataPortal_Fetch(object criteria)
{
Criteria crit = (Criteria)(criteria);
Expand Down
25 changes: 8 additions & 17 deletions Source/Csla/ApplicationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using System.ComponentModel;
using Csla.Server;
using System.Diagnostics.CodeAnalysis;
using Csla.Configuration;

namespace Csla
{
Expand All @@ -26,12 +27,17 @@ public class ApplicationContext
/// Creates a new instance of the type
/// </summary>
/// <param name="applicationContextAccessor"></param>
public ApplicationContext(ApplicationContextAccessor applicationContextAccessor)
/// <param name="options"></param>
public ApplicationContext(ApplicationContextAccessor applicationContextAccessor, CslaOptions options)
{
ApplicationContextAccessor = applicationContextAccessor;
ApplicationContextAccessor.GetContextManager().ApplicationContext = this;
Options = options;
PropertyChangedMode = Options.BindingOptions.PropertyChangedMode;
}

internal CslaOptions Options { get; }

internal ApplicationContextAccessor ApplicationContextAccessor { get; set; }

/// <summary>
Expand Down Expand Up @@ -183,26 +189,11 @@ public enum ExecutionLocations
Server
}

private PropertyChangedModes _propertyChangedMode;
private bool _propertyChangedModeSet;

/// <summary>
/// Gets or sets a value specifying how CSLA .NET should
/// raise PropertyChanged events.
/// </summary>
public PropertyChangedModes PropertyChangedMode
{
get
{
if (!_propertyChangedModeSet)
{
var options = GetRequiredService<Configuration.CslaOptions>();
_propertyChangedMode = options.BindingOptions.PropertyChangedMode;
_propertyChangedModeSet = true;
}
return _propertyChangedMode;
}
}
public PropertyChangedModes PropertyChangedMode { get; }

/// <summary>
/// Enum representing the way in which CSLA .NET
Expand Down
2 changes: 2 additions & 0 deletions Source/Csla/BusinessBindingListBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ ApplicationContext IUseApplicationContext.ApplicationContext
set
{
ApplicationContext = value;
if (ApplicationContext == null)
throw new InvalidOperationException("ApplicationContext == null");
InitializeIdentity();
Initialize();
AllowNew = true;
Expand Down
2 changes: 2 additions & 0 deletions Source/Csla/BusinessListBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ ApplicationContext IUseApplicationContext.ApplicationContext
set
{
ApplicationContext = value;
if (ApplicationContext == null)
throw new InvalidOperationException("ApplicationContext == null");
InitializeIdentity();
Initialize();
AllowNew = true;
Expand Down
6 changes: 3 additions & 3 deletions Source/Csla/Configuration/Fluent/CoreOptions.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
//-----------------------------------------------------------------------
// <copyright file="HttpProxyOptions.cs" company="Marimer LLC">
// <copyright file="CoreOptions.cs" company="Marimer LLC">
// Copyright (c) Marimer LLC. All rights reserved.
// Website: https://cslanet.com
// </copyright>
// <summary>Options for data binding</summary>
// <summary>Internal class used to configure CSLA .NET</summary>
//-----------------------------------------------------------------------

namespace Csla.Configuration
{
/// <summary>
/// Options for data binding
/// Internal class used to configure CSLA .NET
/// </summary>
public class CoreOptions;
}
16 changes: 16 additions & 0 deletions Source/Csla/Configuration/Fluent/CslaOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,22 @@ public CslaOptions RegisterPropertyInfoFactory<
return this;
}

/// <summary>
/// Indicates whether the data annotations scan is disabled.
/// </summary>
public bool ScanDataAnnotations { get; private set; } = true;

/// <summary>
/// Configures the scanning for data annotations based on the provided flag.
/// </summary>
/// <param name="flag">Indicates whether to disable the scanning for data annotations.</param>
/// <returns>Returns the current instance of CoreOptions.</returns>
public CslaOptions ScanForDataAnnotations(bool flag)
{
ScanDataAnnotations = flag;
return this;
}

/// <summary>
/// Gets the SecurityOptions instance.
/// </summary>
Expand Down
5 changes: 4 additions & 1 deletion Source/Csla/Core/BusinessBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ protected BusinessBase()
/// </summary>
protected override void OnApplicationContextSet()
{
if (ApplicationContext == null)
throw new InvalidOperationException("ApplicationContext == null");
InitializeIdentity();
Initialize();
InitializeBusinessRules();
Expand Down Expand Up @@ -1158,7 +1160,8 @@ void IHostRules.AllRulesComplete()
/// </remarks>
protected virtual void AddBusinessRules()
{
BusinessRules.AddDataAnnotations();
if (ApplicationContext.Options.ScanDataAnnotations)
BusinessRules.AddDataAnnotations();
}

/// <summary>
Expand Down
2 changes: 2 additions & 0 deletions Source/Csla/DynamicBindingListBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ ApplicationContext IUseApplicationContext.ApplicationContext
set
{
ApplicationContext = value;
if (ApplicationContext == null)
throw new InvalidOperationException("ApplicationContext == null");
InitializeIdentity();
Initialize();
AllowNew = true;
Expand Down
Loading
Loading