Easy way to allow options only when other is present using CommandLineParserLibrary - c#

I am trying to implement logic using this library:
I have the verb write, and options by this scheme:
write (-md [-p|-s] [-t]) | (-txt [-v]) - where '|' - means or (only -p OR -s is accepted (but not necessary as shown by '[]') when using -md)
Is there easy way to implement this? or should I split this to separate verbs?

Sorry for answering own question but it would be helpful to someone else (source):
You can use use SetName argument while declaring OptionAttribute:
internal class Options
{
[Option("username", SetName = "auth")]
public string Username { get; set; }
[Option("password", SetName = "auth")]
public string Password { get; set; }
[Option("guestaccess", SetName = "guest")]
public bool GuestAccess { get; set; }
}
Now username and password can be used together, but guestaccess is alone within "guest" set, so it can not be used with options from other sets.

Related

Where should I place validation - for example: a comment can't contain some words? In a command handler or in a domain?

I have the aggregate root "Post" and sub entity "Comment".
I have two questions:
An user cannot add a comment which contains a word "drugs". Should I validate it in a command handler or maybe in sub entity "Comment"?
A admin cannot change a comment status from New / Accepted / Rejected to New. Should I validate it in a command handler or maybe in sub entity "Comment"?
My command handler - here I placed validation for "drugs" but I am not sure if I am right:
public class CreateCommentCommand : IRequest
{
public Guid CommentId { get; }
public Guid PostId { get; }
public string Author { get; }
public string Content { get; }
public CreateCommentCommand(Guid commentId, Guid postId, string author, string content)
{
CommentId = commentId;
PostId = postId;
Author = author;
Content = content;
}
}
public class CreateCommentCommandHandler : IRequestHandler<CreateCommentCommand>
{
public async Task<Unit> Handle(CreateCommentCommand request, CancellationToken cancellationToken)
{
if (request.Content.Contains("drugs"))
{
throw new Exception("Forbidden words");
}
// ....
return Unit.Value;
}
}
My sub entity "Comment" - here I placed validation for the comment status but I am not sure if I am right:
public class Comment : Entity
{
public Guid CommentId { get; private set; }
public string Author { get; private set; }
public string Content { get; private set; }
public CommentStatus CommentStatus { get; private set; }
public Comment(Guid commentId, string author, string content)
{
CommentId = commentId;
Author = author;
Content = content;
CommentStatus = CommentStatus.New;
}
public void ChangeStatus(CommentStatus commentStatus)
{
if (commentStatus == CommentStatus.New)
{
throw new Exception("Cannot change status to New");
}
CommentStatus = commentStatus;
}
}
In a command handler or in a domain?
The usual answer is "in the domain". The supporting argument is that the requirements you are describing are best understood as business policy implementation, and business policy is typically a domain concern, rather than a plumbing concern.
You might consider, for example, what should change if the policy changes from "reject" the comment to something like "put the comment in a moderation queue until reviewed".
Another way of thinking about this is to recognize that this is the sort of thing that you ought to be able to test without introducing a bunch of asycn/await constructs.
That said, please notice the "usual answer" hedge: a design isn't good because some rando on stack overflow said so, or because it follows the pattern described in The Book. A design is good if it meets your current and future needs -- in other words, written in the way that you, and future you, and other contributors need it to be written.
The future is hard to know, so we make our best guess based on what we have learned from experience (some learned from our own mistakes, most learned from the mistakes of others -- we hope).

CommandLineParser: get Name of Mutually Exclusive Options Set

Using CommandLineParser I can define a set of mutually exclusive options like this (taken from the wiki):
class OptionsMutuallyExclusive
{
//define commands in set(group) named web
[Option(SetName = "web")]
public string DocumentRoot { get; set; }
[Option(SetName = "web")]
public bool EnableJavaScript { get; set; }
//define other commands in set(group) named ftp
[Option(SetName = "ftp")]
public string FtpDirectory { get; set; }
[Option(SetName = "ftp")]
public bool AnonymousLogin { get; set; }
//Common: the next option can be used with any set because it's not included in a set
[Option('r')]
public string UrlAddress { get; set; }
}
Now I can parse this my app like this (.Dump() coming from LinqPad)
var result = parser.ParseArguments<OptionsMutuallyExclusive>(args);
result.WithParsed(options => options.Dump()).WithNotParsed(errs => errs.Dump());
And will get a positive result (WithParsed) using the following args:
--enablejavascript --documentroot ~/var/local/website -r http://localhost
--ftpdirectory ~/var/local/ftpsite --anonymouslogin -r ftp://myftp.server
And will get an error (WithNotParsed) on this:
--enablejavascript --anonymouslogin
But: Is there any way to tell, which set was used?
So getting the value web on the first call and the value ftp on the second one? Or by using an interface and/or derived classes getting an typed result like WebOptions and FtpOptions?
Using different classes I can call ParseArguments multiple times until it succeeds but this isn't really nice.
All examples I could find are always trying to determine the current set by testing which values are defined and which are not.
Is there any thing I'm missing?
Any alternative?

Routing with regular expressions in ServiceStack

I'm trying to build a small .NET Core server with ServiceStack and would like to use regular expressions for routing. So far I've basically just created a Hello World project and connected it to database.
I have these classes in my ServiceModel project:
[Route("/hello/{Language}/{Name*}", Matches = #"PathInfo =~ \/hello\/[a-z]{2}\/[A-Za-z]+$")]
public class HelloTo : IReturn<HelloResponse> {
public string Language { get; set; }
public string Name { get; set; }
}
[Route("/hello/{Language*}", Matches = #"PathInfo =~ \/hello\/[a-z]{2}$")]
public class Hello : IReturn<HelloResponse> {
public string Language { get; set; }
}
public class HelloResponse {
public string Result { get; set; }
}
and this in my ServiceInterface project:
public HelloResponse Any(HelloTo request) {
var greeting = Db.SingleById<Greeting>(request.Language);
return new HelloResponse { Result = $"{greeting.Text}, {request.Name}!" };
}
public HelloResponse Any(Hello request) {
var greeting = Db.SingleById<Greeting>(request.Language);
return new HelloResponse { Result = $"{greeting.Text}, you!" };
}
The point is, when I send e.g. this request: http://localhost/hello/fr, it goes to the first route, even though it has no Name in it.
As far as I can tell, the second route is inaccesible with this configuration. After some experimentation, it seems to me as if the Matches parameter is completely ignored, which makes me think that maybe I need to enable something. However, I couldn't find much documentation on this, besides a short note here that routing using regexps should be possible somewhat like this.
Note that if I changed the second route from Route("/hello/{Language*}" to Route("/hello/{Language}", this sample will work as expected, presumably because routes without wildcards take precedence, but I need routes ending with wildcards like this for it to be of any practical use.
This issue was due to Matches rules not being validated for wildcard routes which is now resolved from this commit where your example will work as expected from ServiceStack v5.0.3 that's now available on MyGet.

Querying LDAP using expression tree [duplicate]

I want to access to ActiveDirectory using LINQ to LDAP and I want to Get List of All users in that
how can I do that?
You can try something like below.
using ActiveDs;
using BdsSoft.DirectoryServices.Linq;
using System.Linq.Expressions;
using System.DirectoryServices;
[DirectorySchema( "user", typeof( IADsUser ) )]
class User
{
public string Name { get; set; }
public string sAMAccountName { get; set; }
public string objectCategory { get; set; }
public string mail { get; set; }
public string Description { get; set; }
[DirectoryAttribute( "PasswordLastChanged", DirectoryAttributeType.ActiveDs )]
public DateTime PasswordLastSet { get; set; }
[DirectoryAttribute("distinguishedName")]
public string Dn { get; set; }
[DirectoryAttribute("memberOf")]
public string[] Groups { get; set; }
}
Use this code to access AD from a console app, placing your AD server in the below code:
static void Main( string[] args )
{
IEnumerable<User> users = GetADUsers();
Console.WriteLine( "Users: " + users.Count().ToString() );
}
static DirectoryEntry ROOT = new DirectoryEntry( "LDAP://MyADDomainLocation.com" );
private static IEnumerable<User> GetADUsers()
{
IEnumerable<User> users;
var usersDS = new DirectorySource<User>( ROOT, SearchScope.Subtree );
users = from usr in usersDS
where usr.Name == "A*" // FIlter A then any character(s)
select usr;
users = users.OrderBy( user => user.Name ).ToList(); // Sort them alphabetically by name.
return users;
}
For more information check Get All Users using C# with Linq To Active Directory
and LINQ to LDAP
For .NET Core or Standard, please see Chris D's answer, below.
For get comprehensive knowledge about this subject check (Almost) Everything In Active Directory via C#
I hope this will help to you.
Sorry to reply to such an old question, but I felt it needed an updated answer. I wrote a .NET Standard library for this:
Linq2Ldap.Core (NuGet, GitHub) The platform-independent core library that can translate from Expressions into LDAP filters, and parse them back out, again.
It has two wrapper libraries for Active Directory:
Linq2Ldap.Protocols (NuGet, GitHub) - A thin wrapper around Linq2Ldap.Core + System.DirectoryServices.Protocols.
Linq2Ldap (NuGet, GitHub) - A thin wrapper for System.DirectoryServices.
The heart of it can transpile between Expression<Func<T, bool>>s and LDAP filters. The models (T) referenced by the Expressions must implement an interface, IEntry, that basically defines a fancy indexer class that you'd use like this: m => m["cn"] == "someuser". You can also create special properties to alias your directory attributes, too. Please see the project wiki for more info.

Should I use static method (C#)

Should I use static in the following 2 cases:
Case 1)
public class RequestHeader
{
private string Username { get; set; }
private string Password { get; set; }
private string AccessKey { get; set; }
public string url { get; set; }
public string pageid { get; set; }
public string organizationid { get; set; }
private RequestHeader()
{
}
public static RequestHeader GetRequestHeader(string url, string pageid, string organizationid)
{
return new RequestHeader()
{
Username = "Some logic to fetch username",
Password = "Some logic to fetch password",
AccessKey = "Some access key",
url = url,
pageid = pageid,
organizationid = organizationid,
};
}
}
Case 2)
public class HttpClientHelper
{
public static HttpClient GetHttpClient(RequestHeader header)
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
foreach (var property in header.GetType().GetProperties())
{
client.DefaultRequestHeaders.Add(property.Name, property.GetValue(header).ToString());
}
return client;
}
}
I know that static is not used where state is maintained. I believe I am not maintaining any state here. I will be using this in a class library and I will be using these for calling a rest service.
The only thing which makes me want to use static here is not to initialize these class.(I know this is a very baaad reason).
Please let me know your thoughts. Is there something which I am not seeing in this.
Note: 1) I am aware of the small casing for some of the properties. It is in sync with the rest service on which I have absolutely no control.
2) If I have multiple RequestHeader in future, I might create an IRequestHeader which has a method GetRequestHeader. So the different RequestHeaders will implement this. In this case I know I cant keep a static method in interface.
Please Keep these 2 conditions away and let me know your thoughts.
What you have here seems to be a version of the Static Factory Pattern. This is a well-known pattern and is perfectly fine to use.
You might also be interested in the non-static version of the Factory Pattern.
I assume HttpClient is not "your class", in which case you of course can't add a method inside the class itself.
The only thing which makes me want to use static here is not to initialize these class.(I know this is a very baaad reason).
Technically you're instantiating and initializing these classes no matter how you do it (factory method or no factory method), the only question is if you are going to use a factory method to do the instantiation and initialization for you.
If you have to use same values for each call you should use static fields, because static fields are used when only one copy of the variable is required. The same static field will share the copy across all the instances.

Categories