I want to create a struct that stores variables that can't be seen directly but can be modified by public functions.
As much as possible, I want to define all this using protocols and extensions with default implementations.
Here's my first try (this can be pasted directly into a Playground):
import Foundation
private protocol VariablesIWantToHide {
var numGerbils: Int { get set }
var numHamsters: Int { get set }
}
protocol MethodsIWantToAccess {
mutating func setGerbilCount(amount: Int)
mutating func setHamsterCount(amount:Int)
}
protocol MultiAccess: VariablesIWantToHide, MethodsIWantToAccess {}
extension MultiAccess {
mutating func setGerbilCount(amount: Int) {
numGerbils = amount
}
mutating func setHamsterCount(amount: Int) {
numHamsters = amount
}
}
struct MultiAccessStruct: MultiAccess {
var numGerbils: Int = 0
var numHamsters: Int = 0
}
This generates the error message error: protocol must be declared private because it refines a private protocol.
The overall goal is the extension MultiAccess part, where I define default public functions that manipulate private variables. Can this be done?
It generates an error message as protocol MultiAccess has an access control of internal since no explicit access control modifier is specified .
Since it refines protocol VariablesIWantToHide which is private , MultiAccess should also be private as per the access control guiding principle which is
"No entity can be defined in terms of another entity that has a lower (more restrictive) access level"
The goal to access private internal variables using public functions cannot be achieved using extensions with default implementation as an extensions access level can always be less than or equal to the class/protocol that it is extending.
Related
Core Question:
I have a generic interface IValidatingAttribute<T>, which creates the contract bool IsValid(T value); The interface is implemented by a variety of Attributes, which all serve the purpose of determining if the current value of said Field or Property they decorate is valid per the interface spec that I'm dealing with. What I want to do is create a single validation method that will scan every field and property of the given model, and if that field or property has any attributes that implement IValidatingAttribute<T>, it should validate the value against each of those attributes. So, using reflection I have the sets of fields and properties, and within those sets I can get the list of attributes. How can I determine which attributes implement IValidatingAttribute and then call IsValid(T value)?
background:
I am working on a library project that will be used to develop a range of later projects against the interface for a common third party system. (BL Server, for those interested)
BL Server has a wide range of fairly arcane command structures that have varying validation requirements per command and parameter, and then it costs per transaction to call these commands, so one of the library requirements is to easily define the valdiation requirements at the model level to catch invalid commands before they are sent. It is also intended to aid in the development of later projects by allowing developers to catch invalid models without needing to set up the BL server connections.
Current Attempt:
Here's where I've gotten so far (IsValid is an extension method):
public interface IValidatingAttribute<T>
{
bool IsValid(T value);
}
public static bool IsValid<TObject>(this TObject sourceObject) where TObject : class, new()
{
var properties = typeof(TObject).GetProperties();
foreach (var prop in properties)
{
var attributeData = prop.GetCustomAttributesData();
foreach (var attribute in attributeData)
{
var attrType = attribute.AttributeType;
var interfaces = attrType.GetInterfaces().Where(inf => inf.IsGenericType).ToList();
if (interfaces.Any(infc => infc.Equals(typeof(IValidatingAttribute<>))))
{
var value = prop.GetValue(sourceObject);
//At this point, I know that the current attribute implements 'IValidatingAttribute<>', but I don't know what T is in that implementation.
//Also, I don't know what data type 'value' is, as it's currently boxed as an object.
//The underlying type to value will match the expected T in IValidatingAttribute.
//What I need is something like the line below:
if (!(attribute as IValidatingAttribute<T>).IsValid(value as T)) //I know this condition doesn't work, but it's what I'm trying to do.
{
return false;
}
}
}
return true;
}
}
Example usage:
Just to better explain what I am trying to achieve:
public class SomeBLRequestObject
{
/// <summary>
/// Required, only allows exactly 2 alpha characters.
/// </summary>
[MinCharacterCount(2), MaxCharacterCount(2), IsRequired, AllowedCharacterSet(CharSets.Alpha))]
public string StateCode {get; set;}
}
And then, later on in code:
...
var someBLObj = SomeBLRequestObjectFactory.Create();
if(!someBLObj.IsValid())
{
throw new InvalidObjectException("someBLObj is invalid!");
}
Thank you, I'm really looking for a solution to the problem as it stands, but I'm more than willing to listen if somebody has a viable alternative approach.
I'm trying to go generic extension method with this because there are literally hundreds of the BL Server objects, and I'm going with attributes because each of these objects can have upper double digit numbers of properties, and it's going to make things much, much easier if the requirements for each object are backed in and nice and readable for the next developer to have to use this thing.
Edit
Forgot to mention : This Question is the closest I've found, but what I really need are the contents of \\Do Something in TcKs's answer.
Well, after about 6 hours and a goods nights sleep, I realized that I was over-complicating this thing. Solved it with the following (ExtValidationInfo is the class that the below two extensions are in.):
Jon Skeet's answer over here pointed me at a better approach, although it still smells a bit, this one at least works.
public static bool IsValid<TObject>(this TObject sourceObject) where TObject : class, new()
{
var baseValidationMethod = typeof(ExtValidationInfo).GetMethod("ValidateProperty", BindingFlags.Static | BindingFlags.Public);
var properties = TypeDataHandler<TObject>.Properties;
foreach (var prop in properties)
{
var attributes = prop.GetCustomAttributes(typeof(IValidatingAttribute<>)).ToList();
if (!attributes.Any())
{
continue; // No validators, skip.
}
var propType = prop.PropertyType;
var validationMethod = baseValidationMethod.MakeGenericMethod(propType);
var propIsValid = validationMethod.Invoke(null, prop.GetValue(sourceObject), attributes);
if(!propIsValid)
{
return false;
}
}
return true;
}
public static bool ValidateProperty<TPropType>(TPropType value, List<IValidatingAttribute<TPropType>> validators)
{
foreach (var validator in validators)
{
if (!validator.IsValid(value))
{
return false;
}
}
return true;
}
I have this question about get set accessors in C#.
{
private string _mvalue
public string MyValue
{
get
{
return mvalue;
}
set
{
_mvalue = value;
}
}
Here, _mvalue is private. We made it private so that it should not be accessible outside the class.
But then again, we created a property 'MyValue' over this private variable. Using property we can access the private variable.
So don't you think we are compromising over the privateness of the variable. I mean, the variable is meant to be private. But, with the help of proprties, outsiders can still access this variable
_mvalue is not created to make the value of MyValue private. _mvalue is required to maitain the state of the public propery MyValue. No user of this object can access _mvalue as long as it is private. Also, MyValue may contain a different value than _mvalue. For example, you could return _mvalue+"/". Add to this the fact that not every private field like _mvalue need to have a public property of course.
There are several ways to prevent access to a data variable such as:
Use private members only
use a private property
The confusion may be reduced by using Automatic Properties, refer to the accepted answer in: Automatic Property.
This is perfectly fine. No one is making you add a public property to your class. If you really want _mvalue to really stay private, just don't make the public property that uses it.
Usually, we go for private variables in property when we want to do some additionally operations during set or get of the value. For example I always want to multiple the assigned value with 5, in that case we can use some thing like this
public int A
{
get
{
return a;
}
set
{
a=value*5;
}
}
But if you just want to store a value that should be accessed by outside the class in that case you can write a property with out private variable as below
public int A
{
get;
set;
}
if you want only to expose the value, but no one should set the value out side the class then you can even make set as private.
Always property is to expose the values outside the class, but it depends on your logic how you want to write, you can use private variables within that or you needed not, usually private variable is used with the property when it is Bind the to Wpf controls(MVVM) to implement INotifyPropertyChanged.
If your using private variable in a property without any custom logic in get or set, then it is bad programming style, it is like exposing a private member out side the class
First thing is the private variable "_mvalue" cannot be accessed from
outside world as it is Private. Secondly, if you want to really
protect "MyValue", ie, outsiders can access only "Get" property, then
use private keyword with "set".
private string _mvalue;
public string MyValue
{
get
{
return _mvalue;
}
private set
{
_mvalue = value;
}
}
whats difference between Auto-Implemented Properties and manual properties in c#?
for Example:
Manual Properties:
private int uno;
public int Uno
{
get { return uno; }
set { uno = value; }
}
Auto Implemented Prop:
public string UserLeaveCount { get; set; }
i found the difference and uses here : Auto Implemented Prop
But Here is my Specific doubt thats "there is no instance variable in auto implemented properties and how is it stored,returned values?"
It's just syntactic sugar -- the compiler inserts the backing field for you. The effect is the same, except that, of course, there's no way for you to access the backing field from your code.
From the page you linked to:
When you declare a property as shown in the following example, the compiler creates a private, anonymous backing field that can only be accessed through the property's get and set accessors.
I have been building a new .NET solution with Castle performing my DI.
Its now at the stage where i would like to control the order in which my installers run. I have built individual classes which implement IWindsorInstaller to handle my core types — eg IRepository, IMapper and IService to name a few.
I see that its suggested i implement my own InstallerFactory (guessing i just override Select) in this class.
Then use this new factory in my call to:
FromAssembly.InDirectory(new AssemblyFilter("bin location"));
My question — when overriding the save method — what is the best way to force the order of my installers.
I know its already solved but I couldn't find any example on how to actually implement the InstallerFactory so here's a solution if anyone is googling for it.
How to use:
[InstallerPriority(0)]
public class ImportantInstallerToRunFirst : IWindsorInstaller
{
public void Install(IWindsorContainer container, Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store)
{
// do registrations
}
}
Just add the InstallerPriority attribute with a priority to your "install-order-sensitive" classes. Installers will be sorted by ascending. Installers without priority will default to 100.
How to implement:
public class WindsorBootstrap : InstallerFactory
{
public override IEnumerable<Type> Select(IEnumerable<Type> installerTypes)
{
var retval = installerTypes.OrderBy(x => this.GetPriority(x));
return retval;
}
private int GetPriority(Type type)
{
var attribute = type.GetCustomAttributes(typeof(InstallerPriorityAttribute), false).FirstOrDefault() as InstallerPriorityAttribute;
return attribute != null ? attribute.Priority : InstallerPriorityAttribute.DefaultPriority;
}
}
[AttributeUsage(AttributeTargets.Class)]
public sealed class InstallerPriorityAttribute : Attribute
{
public const int DefaultPriority = 100;
public int Priority { get; private set; }
public InstallerPriorityAttribute(int priority)
{
this.Priority = priority;
}
}
When starting application, global.asax etc:
container.Install(FromAssembly.This(new WindsorBootstrap()));
You can call your installers in the order they need to be instantiated in Global.asax.cs or e.g. in a Bootstrapper class, which is called from Global.asax.cs.
IWindsorContainer container = new WindsorContainer()
.Install(
new LoggerInstaller() // No dependencies
, new PersistenceInstaller() // --""--
, new RepositoriesInstaller() // Depends on Persistence
, new ServicesInstaller() // Depends on Repositories
, new ControllersInstaller() // Depends on Services
);
They are instantiated in this order, and you can add a breakpoint after and check the container for "Potentially misconfigured components".
If there are any, check their Status->details, if not, it's the correct order.
This solution is quick and easy, the documentation mentions using a InstallerFactory Class for tighter control over your installers so if you have a ton of installers the other solution may fit better. (Using code as convention should not require tons of installers?)
http://docs.castleproject.org/Windsor.Installers.ashx#codeInstallerFactorycode_class_4
In the end i had to use InstallerFactory and implement the ordering rules as suggested previously by returning the IEnumerable<Type> with my specific order
I know that the Specification pattern describes how to use a hierarchy of classes implementing ISpecification<T> to evaluate if a candidate object of type T matches a certain specification (= satisfies a business rule).
My problem : the business rule I want to implement needs to evaluate several objects (for example, a Customer and a Contract).
My double question :
Are there typical adaptations of the Specification patterns to achieve this ? I can only think of removing the implementation of ISpecification<T> by my specification class, and taking as many parameters as I want in the isSatisfiedBy() method. But by doing this, I lose the ability to combine this specification with others.
Does this problem reveal a flaw in my design ? (i.e. what I need to evaluate using a Customer and a Contract should be evaluated on another object, like a Subscription, which could contain all the necessary info) ?
In that case (depending on what the specification precisely should do, I would use one of the objects as specification subject and the other(s) as parameter.
Example:
public class ShouldCreateEmailAccountSpecification : ISpecification<Customer>
{
public ShouldCreateEmailAccountSpecification(Contract selectedContract)
{
SelectedContract = selectedContract;
}
public Contract SelectedContract { get; private set; }
public bool IsSatisfiedBy(Customer subject)
{
return false;
}
}
Your problem is that your specification interface is using a generic type parameter, which prevents it from being used for combining evaluation logic across different specializations (Customer,Contract) because ISpecification<Customer> is in fact a different interface than ISpecification<Contract>. You could use Jeff's approach above, which gets rid of the type parameter and passes everything in as a base type (Object). Depending on what language you are using, you may also be able to pull things up a level and combine specifications with boolean logic using delegates. C# Example (not particularly useful as written, but might give you some ideas for a framework):
ISpecification<Customer> cust_spec = /*...*/
ISpecification<Contract> contract_spec = /*... */
bool result = EvalWithAnd( () => cust_spec.IsSatisfiedBy(customer), () => contract_spec.IsSatisfiedBy( contract ) );
public void EvalWithAnd( params Func<bool>[] specs )
{
foreach( var spec in specs )
{
if ( !spec() )
return false; /* If any return false, we can short-circuit */
}
return true; /* all delegates returned true */
}
Paco's solution of treating one object as the subject and one as a parameter using constructor injection can work sometimes but if both objects are constructed after the specification object, it makes things quite difficult.
One solution to this problem is to use a parameter object as in this refactoring suggestion: http://sourcemaking.com/refactoring/introduce-parameter-object.
The basic idea is that if you feel that both Customer and Contract are parameters that represent a related concept, then you just create another parameter object that contains both of them.
public class ParameterObject
{
public Customer Customer { get; set; }
public Contract Contract { get; set; }
}
Then your generic specification becomes for that type:
public class SomeSpecification : ISpecification<ParameterObject>
{
public bool IsSatisfiedBy(ParameterObject candidate)
{
return false;
}
}
I don't know if I understood your question.
If you are using the same specification for both Customer and Contract, this means that you can send the same messages to both of them. This could be solved by making them both to implement an interface, and use this interface as the T type. I don't know if this makes sense in your domain.
Sorry if this is not an answer to your question.