3

I have the following two interfaces:

public interface IMembershipProvider
{
    object Login(ILoginProviderParameters loginParameters);
    void SetAuthCookie(string userName, bool createPersistentCookie);
}

public interface IFacebookMembershipProvider : IMembershipProvider{}

and an implimentation:

public class FacebookMembershipProvider: IFacebookMembershipProvider
{
    public object Login(ILoginProviderParameters loginParameters)
    {
        // Facebook login code is here
    }

    public void SetAuthCookie(string userName, bool createPersistentCookie)
    {
        FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
    }
}

This is being injected into my controller and assigned to:

private readonly IFacebookMembershipProvider _facebookMembershipProvider;

I'm able to call the Login method without any issue however when I call the SetAuthCookie method:

_facebookMembershipProvider.SetAuthCookie(user.id, false);

I receive the error:

MyNamespace.UserManagement.Interfaces.IFacebookMembershipProvider' does not contain a definition for 'SetAuthCookie'

What am I doing differently with the Login method that I'm not doing with the SetAuthCookie method?

Explicitly casting to the type IMembershipProvier works just fine:

((IMembershipProvider)_facebookMembershipProvider).SetAuthCookie(user.id, false);

I've probably just missed something rudimentary. Thanks for taking a look.

UPDATE

In response to Marks question, the first parameter being passed to the SetAuthCookie method comes from a dynamic object.

dynamic user = _authorizeUserCommand.Invoke(_authorizeUserParams);
Jamie Dixon
  • 53,019
  • 19
  • 125
  • 162
  • +1 It is hard to believe. No old DLLs knocking around your machine? Could it be Resharper/similar old cache? – Aliostad Mar 23 '12 at 09:52
  • 1
    Are you using anything like `dynamic`, or any decorator platforms, or anything like that? any meta-programming or IoC/DI stacks? Basically, it looks like some code (typically meta-programming, via ILGenerator) is trying to call the method incorrectly. It doesn't *sound* like something the C# compiler would get wrong. – Marc Gravell Mar 23 '12 at 09:55
  • I'm having the same issue locally and on my external server. I've removed and re-added the reference to my UserManagement DLL. It seems like it could be a cache issue though. – Jamie Dixon Mar 23 '12 at 09:55
  • Where is the `IFacebookMembershipProvider` interface? – papaiatis Mar 23 '12 at 09:55
  • One of the parameters being passed to the SetAuthCookie method comes from a dynamic object. `dynamic user = _authorizeUserCommand.Invoke(_authorizeUserParams);` – Jamie Dixon Mar 23 '12 at 09:56
  • and I use Castle Windsor for IoC/DI – Jamie Dixon Mar 23 '12 at 09:57
  • @Jamie k; that could *also* potentially be related, but try the `dynamic` thing first... – Marc Gravell Mar 23 '12 at 10:01

1 Answers1

5

The curse of dynamic (comments)! Dynamic bleeds. In particular, as soon as you involve dynamic in an expression, the entire thing is performed with dynamic rules, which introduces subtle changes into a number of points.

My advice: resolve the value first:

string id = user.id; // this has an implicit cast to string
_facebookMembershipProvider.SetAuthCookie(id, false);

which should work fine. You could also use:

_facebookMembershipProvider.SetAuthCookie((string)user.id, false);

since the explicit cast should end the dynamic part of the expression at the argument, so the invoke is not dynamic.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • @JamieDixon so was user Id a `dynamic` object? – Aliostad Mar 23 '12 at 10:28
  • Yeah. I added it into the comments when Mark asked and I'll include it in the question to make it clearer for future readers. – Jamie Dixon Mar 23 '12 at 10:29
  • @Jamie I'm glad we could find a quick fix, but: I can't decide if this is a bug in the c# dynamic binder or not; have added here: http://stackoverflow.com/questions/9837472/should-an-interface-based-method-invoke-that-uses-dynamic-still-obey-c-sharp-m – Marc Gravell Mar 23 '12 at 10:33
  • Nice one. I'll keep a track of that question to see what comes up. – Jamie Dixon Mar 23 '12 at 11:16