Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Portal
  • |
  • Mitglieder
Beiträge von Peter Bucher
Thema: Wie arbeite ich mit ASP.NET MVC 4.7.2, Office 365 AD und Rollen?
Am im Forum: Web-Technologien

Zitat von Abt
Du kannst auch alles erst mal mit Hilfe von Postman versuchen hin zu bekommen, damit Du Dir sicher sein kannst, dass das AAD richtig konfiguriert ist - und Du gegen die richtigen Endpunkte arbeitest.
Keinen Plan was genau du damit meinst. Ich muss wohl nicht händisch Requests prüfen?
Code brauche ich ja nicht mehr als in etwa dem bestehenden Umfang. Schon verwirrend, diese Sache.
Zitat von Abt
Aktuelle Azure Samples sind zB hier, falls es Dir weiter hilft:
Chapter - Enable your Web app to sign-in users using the Microsoft Identity Platform
Woher hast du diese Url? Scheint für ASP.NET Core zu sein; sollte ja trotzdem anwendbar sein. Nur ist es wieder mal mit IMPLICIT GRANT. Das hatte ich ja schon am laufen, möchte ich aber nicht.
Die Beispiele bringen mich nicht weiter. Ich verstehe immer nur weniger.

Mal schauen, ob ich mit dem Tipp vom Papst ;-) weiterkomme...

Thema: Wie arbeite ich mit ASP.NET MVC 4.7.2, Office 365 AD und Rollen?
Am im Forum: Web-Technologien

Hallo Abt

Ja schon gehört. Ist mir aber alles nicht wirklich hilfreich, um ehrlich zu sein.
Folgend ist mein aktueller Code der Startup.cs. Ich habe ihn dem Projekt Template von VS angepasst. So wie ich das verstehe, soll das jetzt Code Auth Flow sein.

Es kommt aber immer noch die genau gleiche Meldung, dass er id_token, etc... für implicit aktiviert haben will.
Und in "AuthorizationCodeReceived" springt er auch nicht.
Wieso ist denn das so?

Der Fehler der immer noch kommt, ist: https://login.microsoftonline.com/error?code=700054


        public void Configuration(IAppBuilder app)
        {
            string clientId = WebConfigurationManager.AppSettings["ClientId"];
            string authority = "https://login.microsoftonline.com/" + WebConfigurationManager.AppSettings["Tenant"] + "/v2.0";
            string appKey = WebConfigurationManager.AppSettings["ClientSecret"];

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions());
            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    // Sets the ClientId, authority, RedirectUri as obtained from web.config
                    ClientId = clientId,
                    Authority = authority,
                    RedirectUri = WebConfigurationManager.AppSettings["RedirectUri"],
                    // PostLogoutRedirectUri is the page that users will be redirected to after sign-out. In this case, it is using the home page
                    PostLogoutRedirectUri = WebConfigurationManager.AppSettings["RedirectUri"],
                    //Scope = OpenIdConnectScope.OpenIdProfile,
                    // ResponseType is set to request the id_token - which contains basic information about the signed-in user
                    //ResponseType = OpenIdConnectResponseType.IdToken,
                    // ValidateIssuer set to false to allow personal and work accounts from any organization to sign in to your application
                    // To only allow users from a single organizations, set ValidateIssuer to true and 'tenant' setting in web.config to the tenant name
                    // To allow users from only a list of specific organizations, set ValidateIssuer to true and use ValidIssuers parameter
                    TokenValidationParameters = new TokenValidationParameters()
                    {
                        ValidateIssuer = false // Simplification (see note below)
                    },
                    // OpenIdConnectAuthenticationNotifications configures OWIN to send notification of failed authentications to OnAuthenticationFailed method
                    Notifications = new OpenIdConnectAuthenticationNotifications
                    {
                        AuthenticationFailed = OnAuthenticationFailed,
                        // If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away.
                        AuthorizationCodeReceived = (context) =>
                        {
                            var code = context.Code;
                            ClientCredential credential = new ClientCredential(clientId, appKey);
                            string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
                            AuthenticationContext authContext = new AuthenticationContext(authority, null);
                            AuthenticationResult result = authContext.AcquireTokenByAuthorizationCodeAsync(
                                code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceId).Result;

                            return Task.FromResult(0);
                        }
                    }
                }
            );
        }

        private Task OnAuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> arg)
        {
            throw new NotImplementedException();
        }


Grüsse

Thema: Welche Datenbank-Technologie? NoSQL oder nicht?
Am im Forum: Datentechnologien

Hallo JimStark

Das Entiyframework ist mit SQLite extrem eingeschränkt, sobald du das Schema ändern möchtest, ist vorbei. Du kannst nur Felder hinzufügen, aber nichts ändern.
Daher SQLServer - auch wegen der Performance wenns grösser wird.


Grüsse

Thema: Wie arbeite ich mit ASP.NET MVC 4.7.2, Office 365 AD und Rollen?
Am im Forum: Web-Technologien

Hi Abt

Das ist doch mal ein Wort. Dann richte ich mich an Authorization Flow, dankeschön! :-)


Grüsse

Thema: Wie kann ich zur Laufzeit neue Properties in ein Objekt hinzufügen?
Am im Forum: GUI: WPF und XAML

Ich glaube witte meint damit, dass es nicht mehr reine Polymorphie ist.

Thema: Wie kann ich zur Laufzeit neue Properties in ein Objekt hinzufügen?
Am im Forum: GUI: WPF und XAML

Hallo CombatKarl

dynamic oder Dictionary<string, object>. Ist aber meistens ein Zeichen, dass da was falsch angegangen wird. Nummeriert Variabeln, wieso? Nutze Arrays oder Listen.


Grüsse

Thema: Wie arbeite ich mit ASP.NET MVC 4.7.2, Office 365 AD und Rollen?
Am im Forum: Web-Technologien

Hallo Abt

So, jetzt bin ich einen Schritt weiter. Die API greift.
Darf ich ohne Probleme den implicitFlow verwenden, wo man die id_token in Azure aktivieren muss?

Siehe:
- https://ingogegenwarth.wordpress.com/2019/03/07/oauth-get-accesstoken/

Scheint ja für Webanwendungen zu sein, oder Mobileanwendungen. Aber da es ja eine externe Auth / Author ist, müsste das passen, oder?

Doch nicht:

Zitat
If you are developing a Web application that includes a backend, and consuming an API from its backend code, the implicit flow is also not a good fit. Other grants give you far more power. For example, the OAuth2 client credentials grant provides the ability to obtain tokens that reflect the permissions assigned to the application itself, as opposed to user delegations. This means the client has the ability to maintain programmatic access to resources even when a user is not actively engaged in a session, and so on. Not only that, but such grants give higher security guarantees. For instance, access tokens never transit through the user browser, they don't risk being saved in the browser history, and so on. The client application can also perform strong authentication when requesting a token.

=> https://docs.microsoft.com/en-gb/azure/active-directory/azuread-dev/v1-oauth2-client-creds-grant-flow

Oh jesses


Grüsse

Thema: Wie arbeite ich mit ASP.NET MVC 4.7.2, Office 365 AD und Rollen?
Am im Forum: Web-Technologien

Hi Abt

Zitat von Abt
Alle Callback-URLs (auch Redirect) müssen korrekt (auch mit zusätzlichem Slash) konfiguriert werden.
Sorry, das habe ich wohl übersehen. Ich schaue mal, ob der zusätzliche Slash da ist! :-)


Danke und Grüsse

Thema: Wie arbeite ich mit ASP.NET MVC 4.7.2, Office 365 AD und Rollen?
Am im Forum: Web-Technologien

Hi Abt

Danke für deine Ausführungen!

Zitat von Abt
Callbacks sind Post, Redirect nicht.
Trotzdem muss in der App Registration auch der Redirect korrekt hinterlegt sein.

In Deinem Beispiel ist der Redirect laut Web.config einfach auf die Root-Url.

Die Callback-Implementierung ist Teil der Middleware und muss nicht selbst implementiert werden.
Ja mir ist dieser Unterschied schon geläufig, nur heisst es in der Doku "RedirectUri" und auch die Beschreibung hört sich überhaupt nicht nach einem Callback an. Die RedirectUri ist 1:1 eingestellt in Azure. Auch die Root Url. Ich nehme an da funkt sonst noch was dazwischen, sodass es die Route nicht findet :-(.

Danke für den Tipp, dass Callback direkt an die interne API geht. Ich sondere mal aus.

Grüsse

Thema: Wie arbeite ich mit ASP.NET MVC 4.7.2, Office 365 AD und Rollen?
Am im Forum: Web-Technologien

Hallo Abt

Ah, Post Redirect haha. Ganz was neues.
Ich habe nirgendwo was von einer Post-CallBack Url gelesen bezüglich Identity. Wo finde ich denn diese Infos? Scheinbar bin blind.

Identity ist der Nachfolger von Membership. Und Owin ist für die Authentifizierung Server/Client.

Aber da gibt es scheinbar Token based (für Apps) und nicht Token based?
So richtig schön übersichtlich ist das also überhaupt nicht.

Im Beispiel finde ich keine Route, die für einen "Post Redirect" genutzt wird.
- https://github.com/AzureADQuickStarts/AppModelv2-WebApp-OpenIDConnect-DotNet/archive/master.zip


Grüsse

Thema: Wie arbeite ich mit ASP.NET MVC 4.7.2, Office 365 AD und Rollen?
Am im Forum: Web-Technologien

Hallo Abt

Habe jetzt Owin (Identity) eingebaut nach der Anleitung, die securityGroups weitergeleitet und alles konfiguriert. Kann jetzt bei Microsoft auf meinen Benutzer klicken, aber nachher will er zurück auf meine Seite und bringt einen 404.

Folgendes ist die RedirectUri die überall drinsteht:

<add key="RedirectUri" value="https://localhost/dashboard"/>

Hier die Login Actionmethode:


        [HttpGet]
        public ActionResult Login(string ReturnUrl = "")
        {
            if (!Request.IsAuthenticated)
            {
                HttpContext.GetOwinContext().Authentication.Challenge(
                    new AuthenticationProperties { RedirectUri = "https://localhost/dashboard" },
                    OpenIdConnectAuthenticationDefaults.AuthenticationType);
            }

Und er bringt einen 404. Wenn ich auf F5 klicke, will er noch einmal einen POST absetzen. Ich frage mich gerade, wo das Problem liegt? Bei localhost?
Fehler
Angeforderter URL: /dashboard

Danke und Grüsse
Peter

Thema: Wie arbeite ich mit ASP.NET MVC 4.7.2, Office 365 AD und Rollen?
Am im Forum: Web-Technologien

Hallo

Gute Info zu Group-Weiterleitung:
- https://odetocode.com/blogs/scott/archive/2018/02/20/role-based-authorization-in-asp-net-core-with-azure-ad.aspx


Grüsse Peter

Thema: Wie kann ich Sendgrid über Azure von http auf https migrieren?
Am im Forum: Web-Technologien

Hi Abt

Danke für die Info!

Grüsse

Thema: Wann setze ich IEnumerable und yield ein?
Am im Forum: Grundlagen von C#

Hi Jim

Hier noch ein wenig Grundlagenwissen dazu:
- https://peterbucher.ch/artikel#ienumerable

@Abt
Der Tipp bezüglich des Materialisierens einer Menge ist wichtig :-)

Grüsse

Thema: Wie kann ich Sendgrid über Azure von http auf https migrieren?
Am im Forum: Web-Technologien

Danke Abt. Als "accepted" kam, kam das Mail an. Es wird nur von einem Hintergrundprozess nicht mehr geschickt, da der Hintergrundprozess ein falsches Ergebnis liefert. Also ein anderes, als ich erwarte.

Das ist ein if :-)

Also alles gut. Die Domain musste ich nie validieren für SendGrid. Muss man das?


Grüsse

Thema: Wie kann ich Sendgrid über Azure von http auf https migrieren?
Am im Forum: Web-Technologien

Hi Abt

Jetzt stand "accepted" drin und es hat geklappt, mit meinem Code.
Komische Sache. Ich prüfe mal, ob es einen anderen Grund gibt zufälligerweise, dass die Emails nicht abgeschickt werden :-)

Danke und Grüsse
Peter

Thema: Wie kann ich Sendgrid über Azure von http auf https migrieren?
Am im Forum: Web-Technologien

Hi Abt

Genau das verwende ich auch. Hast du bei Azure / Sendgrid etwas spezielles eingestellt?
Kannst du mir zeigen, wie du das Email schickst?

Im Moment schicke ich das Email so:


        public static async Task SendMail(string from, IEnumerable<string> to, string subject, string body)
        {
            var apiKey = ConfigurationManager.AppSettings["SENDGRID_APIKEY"];

            var options = new SendGridClientOptions();
            options.ApiKey = apiKey;
            options.Host = "https://api.sendgrid.com";

            var client = new SendGridClient(options);
            var msg = new SendGridMessage()
            {
                From = new EmailAddress(from),
                Subject = subject,
                PlainTextContent = "Hello, Email!",
                HtmlContent = body
            };

            foreach(string recepient in to)
            {
                msg.AddTo(new EmailAddress(recepient));
            }

            var response = await client.SendEmailAsync(msg);
        }

Grüsse

Thema: Wie kann ich Sendgrid über Azure von http auf https migrieren?
Am im Forum: Web-Technologien

Hallo zusammen

Von SendGrid kam eine Email, dass ich ihren Service, der über Azure angemeldet ist, nicht mehr über http, sondern https nutzen muss.
Ich nutze Sendgrid um Emails von einer ASP.NET MVC (Nicht Core) App, zu senden.

Das Email sende ich über das normale nuget Package und beschrieben wie hier:
- https://docs.microsoft.com/en-us/azure/sendgrid-dotnet-how-to-send-email

Ich habe auch versucht, den Endpoint als "https://sendgrid...." anzugeben - also der korrekte - aber die Emails kommen nicht mehr an.

Die Webseite von Sendgrid hilft nicht wirklich weiter. Hoffentlich hat jemand dasselbe Problem und weiss weiter?

Danke und Gruss
Peter

Thema: Wie arbeite ich mit ASP.NET MVC 4.7.2, Office 365 AD und Rollen?
Am im Forum: Web-Technologien

Hallo Abt

Danke für deine Antwort. Phu, ich habe nicht gerne so dicke komplexe APIs. Das meinte ich mit meiner Frage, ob man heute als mit diesem Identity Framework machen muss.

Offensichtlich ist das so, auch das Aufgebau mit Claims oder Policy ist scheinbar nötig und eine Alternative gibt es nicht?

Werde dann wohl nach der offiziellen Anleitung gehen und weiss dass ich das migrieren kann, super!

Zitat
Acht bei der Doku darauf, dass ADAL die alte Auth-API ist.
Die neue Auth-API ist die MSAL. Neue App-Regstrierungen und gewisse AuthN-Level forcieren den MSAL (zB. die Graph API).
Gibts ein Lexikon für AuthN-Level, MSAL, etc? :-) LOL

edit:
Dann muss ich sowieso OWIN einbinden und habe dann mein Problem der fehlenden Startup Klasse nicht mehr :-)


Danke und Grüsse
Peter

Thema: Wie arbeite ich mit ASP.NET MVC 4.7.2, Office 365 AD und Rollen?
Am im Forum: Web-Technologien

Hallo zusammen

Ich muss abklären wie Authentifizierunt / Authorisierung mit Rollen über Office 365 AD in ASP.NET MVC 4.7.2 zu implementieren ist.

So wie ich das sehe, ist der Einstiegspunkt hier?
=> https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-create-new-tenant

Ist jetzt alles "Identity"?
Wie kann ich eine x.IsInRole("xyz") Implementierung umsetzen?
Es besteht schon eine Implementierung mit einer eigenen Identity (Klasse) und einem RoleProvider, kann ich das relativ einfach migrieren?
Bzw. Rollen im AD hinterlegen, die ich dann so abfragen kann?


Danke für Ansatzpunkte.


Grüsse Peter

Thema: Ist es möglich in ASP.NET MVC (nicht Core) die Startup Klasse hinzuzufügen?
Am im Forum: Web-Technologien

Hallo zusammen

Danke Abt, nur will ich da ja nicht Owin einbauen, damit das geht. Schade.

@gfoidl
Doch das geht schon, allerdings nicht für die UI die registriert würde. Die läuft nur über Startup.cs.


Grüsse Peter

Thema: Ist es möglich in ASP.NET MVC (nicht Core) die Startup Klasse hinzuzufügen?
Am im Forum: Web-Technologien

Hallo zusammen

Ist es möglich in ASP.NET MVC (aktuellste Version aber nicht ASP.NET Core) die Startup Klasse auch hinzuzufügen.
Damit wäre es möglich, das Hangfire Dashboard anzuzeigen.

Siehe:
- https://docs.hangfire.io/en/latest/getting-started/aspnet-applications.html


Dank im Voraus und Grüsse
Peter

Thema: Welche ASP.NET Core 3.1.x Hoster (VServer oder Managed) könnt ihr empfehlen?
Am im Forum: Web-Technologien

Hoi Abt

Danke für deine Antwort. Wo kann ich diese Test / Dev Service Instanzen mit Custom Domain und SSL? erstellen?
Ich sehe hier nur relativ teure AppService Instanzen.

B1 Tier: 59.- im Monat. Sonst nur ohne SSL :-(


Gruss Peter

Thema: Welche ASP.NET Core 3.1.x Hoster (VServer oder Managed) könnt ihr empfehlen?
Am im Forum: Web-Technologien

Hallo zusammen

Im Moment habe ich einen Windows VServer in Deutschland, jedoch ist der mittlerweile zu langsam. Ich habe zwei kleine ASP.NET Core Webseiten und eine grössere ASP.NET Core Webseite.
Da ich so wenig Arbeitsspeicher habe, wird die Seite sogar langsamer, wenn ich Caching einschalte.

Die 1GB sind sehr schnell voll :-/.

Jetzt suche ich einen Hoster der ASP.NET Core 3.1.x unterstützt, entweder ein Managed-Modell das preislich für 3 Seiten gut ist oder ein VServer der günstig aber zumindest leistungsfähiger ist, als mein aktueller.

Hat jemand Tipps?


Danke und Gruss Peter

Thema: Wie schaffe ich es OOP zu begreifen und zu lernen?
Am im Forum: Rund um die Programmierung

Hallo PierreDole

Du kannst als Praxisübung auch ein kleines Projekt durchführen. Für mich war früher ein Snake sehr geeignet. Einmal so wie gewohnt, prozedural. Und dann versucht per OOP umzusetzen.

Das geht gut, weil du die einzelnen Teile in Klassen modelieren kannst. Ich fand das eine gute Übung.


Gruss Peter

Thema: Für was ist ein Interface gut?
Am im Forum: Grundlagen von C#

Hallo Frokuss

Abstrakte Klassen und auch ganz "normale" Klassen stellen auch eine Schnittstelle / Abstraktion dar, wie du jetzt mit "Control" gemerkt hast. Schau mal noch nach dem Stichwort "Polymorphie" und "Abstraktion".

Schau mal hier:
- https://peterbucher.ch/artikel#umkehrungteil1

Zitat:

Zitat
Wollen wir diese Abhängigkeit lockern / lösen, brauchen wir eine Abstraktion irgend einer Art.
Das kann ein Interface sein, eine Abstrakte Klasse oder auch eine einfache konkrete Oberklasse.

Vielleicht hilft dir das beim Verständnis.


Gruss Peter

Thema: Visual Studio Online - diesmal als Editor
Am im Forum: Szenenews

Hi Abt

Danke für diese interessante News :-)


Gruss Peter

Thema: mycsharp.de ist nun auf Azure umgezogen
Am im Forum: Ankündigungen

Top Abt! :-)

Thema: Wert aus JSON extrahieren - Mit RegEx?
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo zusammen

Nach dem integralen Gedanken haben meiner Meinung nach schlussendlich alle hier, zumindest zu einem Anteil, Recht. Die die sagen, dass es schöner wäre, hauseigene Bibliotheken von .NET zu benutzen. Wenn möglich, kann man da zustimmen. Auch jene die sagen, dass laut Zeitgeist OpenSource und Pakete die Gegenwart und Zukunft sind.

Es ist schöner, etwas "natives" zu benutzen, ganz meine Meinung. Ich bin auch ein Anhänger von wenigen Abhängigkeiten. Es ist schön das zu haben, aber nicht unbedingt nötig. Der Overhead von der externen Bibliothek im konkreten Fall JSON.NET ist sicher zu vernachlässigen. Es ist auch zu beachten, dass JSON.NET schon seit längerer Zeit ein Standart ist.

Nach dem Grundsatz: "Soviel wie nötig, so wenig wie möglich".

Das Problem entsteht dadurch, dass es verschiedene Ideologien / Ideengebäude gibt, die sich offensichtlich wiedersprechen. Ich denke aber, dass beide zum Teil recht haben und zum anderen Teil auch der anderen Seite recht geben müssten.
Wenn sich alle aneinander annähern und offen sind, ist es nicht nötig alles lang und breit zu diskutieren oder persönlich zu werden. Egal ob anfänglich oder als Reaktion. Es geht um die Sache, nicht um die Ideologie.


Gruss Peter

Thema: Wie kann ich eine Liste mit Events erstellen?
Am im Forum: Grundlagen von C#

Hallo GeneVorph

Ich würde auch zur Interface-Implementation tendieren. Auch denke ich, dass Abt richtig erkannt hat, dass du wohl .NET Events nutzt, wo sie nicht vorgesehen sind und auch keinen Sinn machen.

Du kannst unterscheiden zwischen Interface- / Klassenbasierter Implementierung und Implementierungen mit Funktions-Zeigern (Delegates). Dass ist das was du wohl gesucht hast. Die .NET Events nutzen auch Delegates bspw. den EventHandler oder EventHandler<T>-Typ. Diese sind allerdings dazu da "richtige" Event-Szenarien generisch abzudecken. Was du hier hast, ist eine Spezifizierung einer Schnittstelle die einen Player1 und 2 kennt, sowohl ein Stück Code hat, dass damit ausgeführt werden soll und die Player-Instanzen entsprechend den Regeln verändert.

Du sagst ja: Player1 und Player2 rein und Customcode (void ApplyRule) ausführen, der die Regel beinhaltet und die Player-Instanzen benötigst. Das kann auch mit Instanzen von Funktioneszeigern (Delegaten) umgesetzt werden. Dort sieht das "Interface" so aus: ApplyRule(Player player1, Player player2). Also Players rein und beim ausführen der Funktionsinstanz, Regel anwenden (Die Regel selber, als Funktionsbody implementiert). In beiden Fällen kannst du die Regel sowie die Spieler zuweisen und zu einem gewünschten Zeitpunkt, die Regel(n) anwenden. Das muss nicht gleich bei der Instanziierung passieren.

ps: Action<Player, Player> ist nichts anderes als ein delegate-Typ der X generische Argumente entgegennimmt. Definiert eine Instanz einer Funktion (so kann man sich das vorstellen), die so aussieht: void(player, player) { body }.

- https://msdn.microsoft.com/de-de/library/dd387291(v=vs.110).aspx

Action<T>, Func<T> ist ein interessantes Gebiet, lernreich und kann dann und wann eingesetzt werden.

Hier ein wenig Beispielcode dazu:


using System;
using System.Collections.Generic;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Player player1 = new Player();
            Player player2 = new Player();

            // Interface Implementierung
            List<IRule> rules = new List<IRule>();
            rules.Add(new HandycapRule(5, 0));

            foreach (IRule rule in rules)
            {
                rule.Player1 = player1;
                rule.Player2 = player2;

                // Hier oder zu einem anderne Zeitpunkt Regel anwenden.
                rule.ApplyRule();
            }

            // Funktions-Implementierung (Keine Events nötig, nur Delegates)
            List<Action<Player, Player>> rulesActions = new List<Action<Player, Player>>();

            rulesActions.Add((p1, p2) => p1.Strength -= 5);
            // ...

            // Hier oder zu einem anderen Zeitpunkt wo Player1, Player2 verfügbar sind.
            foreach (var ruleAction in rulesActions)
            {
                ruleAction(player1, player2);
            }

            // Oder
            rulesActions.ForEach(rule => rule(player1, player2));
        }
    }

    public class Player
    {
        public Player()
        {
            this.Strength = 10;
        }

        public string Name { get; set; }
        public int Strength { get; set; }
    }

    // Interface Implementierung

    public interface IRule
    {
        Player Player1 { get; set; }
        Player Player2 { get; set; }

        void ApplyRule();
    }

    // Ginge auch, ist näher an Funktionsimplementierung
    public interface IRuleFunction
    {
        void ApplyRule(Player player1, Player player2);
    }

    public class HandycapRule : IRule
    {
        private int _player1HandycapAmount;
        private int _player2HandycapAmount;

        public HandycapRule(int player1HandycapAmount, int player2HandycapAmount)
        {
            this._player1HandycapAmount = player1HandycapAmount;
            this._player2HandycapAmount = player2HandycapAmount;
        }

        public Player Player1 { get; set; }
        public Player Player2 { get; set; }

        public void ApplyRule()
        {
            this.Player1.Strength -= this._player1HandycapAmount;
            this.Player2.Strength -= this._player2HandycapAmount;
        }
    }
}


Gruss Peter