Coder Social home page Coder Social logo

vahidn / aspnetidentitydependencyinjectionsample Goto Github PK

View Code? Open in Web Editor NEW
32.0 10.0 16.0 1.73 MB

ASP.NET Identity Dependency Injection Sample

License: Apache License 2.0

C# 21.89% CSS 0.08% ASP 0.01% JavaScript 78.02%
asp-net-identity aspnetidentity

aspnetidentitydependencyinjectionsample's Introduction

aspnetidentitydependencyinjectionsample's People

Contributors

vahidn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aspnetidentitydependencyinjectionsample's Issues

Registering IIdentity for SignalR

Thanks a lot for adding this feature. It seems that it has some problems when using SignalR:

public class NotificationHub : Hub
{        
        private readonly IApplicationUserManager _userManager;
        // other dependencies
        public NotificationHub(IApplicationUserManager userManager, ....)
        {
            _userManager = userManager;
            //,....
        }
        //....
}

Exception:

Failure while building 'Lambda: IIF((HttpContext.Current.User != null), IIF((HttpContext.Current != null), HttpContext.Current.User.Identity, null), null)', check the inner exception for details
1.) Lambda: IIF((HttpContext.Current.User != null), IIF((HttpContext.Current != null), HttpContext.Current.User.Identity, null), null)
2.) Instance of System.Security.Principal.IIdentity
3.) new ApplicationUserManager(*Default of IUserStore<ApplicationUser, Int32>*, *Default of IUnitOfWork*, *Default of IIdentity*, *Default of IApplicationRoleManager*, *Default of IDataProtectionProvider*, Lifecycle resolution of MyProject.Service.Entities.SmsService, Lifecycle resolution of MyProject.Service.Entities.EmailService){
    Set IIdentityMessageService EmailService = Lifecycle resolution of MyProject.Service.Entities.EmailService
    Set IIdentityMessageService SmsService = Lifecycle resolution of MyProject.Service.Entities.SmsService
}
4.) MyProject.Service.Entities.ApplicationUserManager
5.) Instance of MyProject.Service.Interfaces.IApplicationUserManager (MyProject.Service.Entities.ApplicationUserManager)
6.) new NotificationHub(*Default of IRequestService*, *Default of IResponseService*, *Default of IApplicationUserManager*)
7.) MyProject.Web.Hubs.NotificationHub
8.) Instance of MyProject.Web.Hubs.NotificationHub
9.) Container.GetInstance(MyProject.Web.Hubs.NotificationHub)

علت عدم استفاده از سرویس جنریک برای عملیات کراد؟

سلام می خواستم بدون چرا در لایه سرویس یک سرویس جنریک برای عملیات کراد ساده نوشته نشده تا همه سرویس ها ازش به ارث برن و دیگه لازم نباشه برای هر سرویس کراد رو پیاده سازی کرد؟ مورد دوم اینکه با توجه به اینکه برگشت دادن اینامریبل در لایه سرویس مشکل آفرین هست به چه صورتی باید متد گت آل رو که نیاز به متد اینکلود داره پیاده سازی کرد؟ آیا به ازای هر گت آل ای که نیاز به اینکلود داره باید یک متد جدا تعریف بشه؟

How to get user profile data inside views?

I want to access user profile information inside my views. for example I have a field called UserAvatar So I want to access this property this way:
User.Identity.GetUserAvatar();
Any idea?

custom errors

با سلام
در صورتی که بخوایم custom error ها رو در این پروژه فعال کنیم برای SEO هم مشکلی ایجاد نشه به چه صورتی عمل بشه بهتر هست؟

Accessing HttpContext.Current.User.Identity.Name in the DbContext

Hello, I'm going to use the UserName for tracking Created and Modified fields. To do that I have referenced to the System.Web assembly directly inside DbContext:

public void auditFields()
 {
            var auditDate = DateTime.Now;
            foreach (var entry in this.ChangeTracker.Entries<BaseEntity>())
            {
                switch (entry.State)
                {
                    case EntityState.Detached:
                        break;
                    case EntityState.Unchanged:
                        break;
                    case EntityState.Added:
                        entry.Entity.CreatedOn = auditDate;
                        entry.Entity.ModifiedOn = auditDate;
                        entry.Entity.CreatedBy = HttpContext.Current.User.Identity.Name ?? "anonymouse";
                        entry.Entity.ModifiedBy = HttpContext.Current.User.Identity.Name ?? "anonymouse";
                        break;
                    case EntityState.Deleted:
                        break;
                    case EntityState.Modified:
                        entry.Entity.ModifiedOn = auditDate;
                        entry.Entity.ModifiedBy = HttpContext.Current.User.Identity.Name ?? "anonymouse";
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
}

It works, But it's tightly coupling the DbContext with HttpContext which is not a good idea in case we'll expose the DbContext to a non-web environment.
So I use this way:

public class ApplicationDbContext :
        IdentityDbContext<ApplicationUser, CustomRole, int, CustomUserLogin, CustomUserRole, CustomUserClaim>,
        IUnitOfWork
{
    public ApplicationDbContext()
            : base("ConnectionString")
        {
        }
        public ApplicationDbContext(string userName)
            : base("ConnectionString")
        {
            UserName = userName;
        }
    //Other codes
    public string UserName
        {
            get;
            private set;
        }
    public void auditFields()
    {
            var auditDate = DateTime.Now;
            foreach (var entry in this.ChangeTracker.Entries<BaseEntity>())
            {
                switch (entry.State)
                {
                    case EntityState.Detached:
                        break;
                    case EntityState.Unchanged:
                        break;
                    case EntityState.Added:
                        entry.Entity.CreatedOn = auditDate;
                        entry.Entity.ModifiedOn = auditDate;
                        entry.Entity.CreatedBy = UserName ?? "anonymouse";
                        entry.Entity.ModifiedBy = UserName ?? "anonymouse";
                        break;
                    case EntityState.Deleted:
                        break;
                    case EntityState.Modified:
                        entry.Entity.ModifiedOn = auditDate;
                        entry.Entity.ModifiedBy = UserName ?? "anonymouse";
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
    }
}

And in the Ioc config project:

ioc.For<IUnitOfWork>()
                   .HybridHttpOrThreadLocalScoped()
                   .Use<ApplicationDbContext>()
                   .Ctor<string>().Is(HttpContext.Current.User.Identity.Name);

But when I run the application I'll get this error in above line:
Object reference not set to an instance of an object
It seems that it can't inject HttpContext.
Any idea?

Business Transaction?

hi !

I'm new in both Asp.net Identity and DI and have some problem understanding the code.

my question is that where the changes are persisted to database , where we call SaveAllChanges?
where is business transaction boundary?

Problem with changing password when using AngularJS

Sallam,
I'm using this code https://github.com/tjoudeh/AngularJSAuthentication and yours. every projects work nice seprately but when i using them in single project, the problem of changing password appears. means that using ApplicationManager in service layer and OAuthentication with AngularJS in UI layer make some wrong things that some of operations do not work . Like changing password or recovery or other things about authority and authentication even like change other filed of ApplicationUser.
So still could not undrastand.
can you help me, please?

Value cannot be null. Parameter name: connection

I'm using Transaction Per Request pattern in my application, but when I apply last two commits of this code I get following exception:

Line 37:             else
Line 38:             {
Line 39:                 transaction.Commit();
Line 40:             }
Line 41:         }

[ArgumentNullException: Value cannot be null.
Parameter name: connection]
   System.Data.Entity.Utilities.Check.NotNull(T value, String parameterName) +44
   System.Data.Entity.Infrastructure.Interception.DbTransactionInterceptionContext.WithConnection(DbConnection connection) +26
   System.Data.Entity.Infrastructure.Interception.DbTransactionDispatcher.Commit(DbTransaction transaction, DbInterceptionContext interceptionContext) +167
   System.Data.Entity.Core.EntityClient.EntityTransaction.Commit() +82

[EntityException: The underlying provider failed on Commit.]
   System.Data.Entity.Core.EntityClient.EntityTransaction.Commit() +165
   System.Data.Entity.DbContextTransaction.Commit() +13
   ProjectName.Web.Infrastructure.TransactionPerRequest.ProjectName.Service.Interfaces.Tasks.IRunAfterEachRequest.Execute() in C:\Users\Sirwa\Documents\Projects\ASP.NET\ProjectName\ProjectName.Web\Infrastructure\TransactionPerRequest.cs:39
   ProjectName.Web.MvcApplication.Application_EndRequest(Object sender, EventArgs e) in C:\Users\Sirwa\Documents\Projects\ASP.NET\ProjectName\ProjectName.Web\Global.asax.cs:124
   System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +141
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +69

PS: It works when I comment this line:
app.CreatePerOwinContext(() => ((ApplicationDbContext)container.GetInstance<IUnitOfWork>()));

Passing params

Hey,

Thanks for sharing the code.

I am a bit new with this and I am trying to pass a connection string parameter to the ApplicationDBContext. Can you please give some tips on that?

Implementing Container Per Request pattern

I'm going to add in the necessary infrastructure to bind each request to its own nested container, So in this case having a Container Per Request gives us a unique session (Context Per Request). But the code doesn't give us this ability, If you just set a break point in the ApplicationDbContext's constructor, You can see each time an instance is created. For example in my case I have these controllers:

public partial class HomeController : Controller
{
        private readonly IUnitOfWork _uow;

        public HomeController(IUnitOfWork uow)
        {
            _uow = uow;
        }
        public virtual ActionResult Index()
        {
            return View();
        }
}
public class TestController : Controller
{
        private readonly IUnitOfWork _uow;

        public TestController(IUnitOfWork uow)
        {
            _uow = uow;
        }

        public ActionResult GetData()
        {
            return Content("Data");
        }
}

So the view returned by Index action uses this code to pull in content from TestController:

@Html.Action("GetData", "Test") 

In that example, several instances are created per request!
So as you mentioned in your blog post, the HTML.Action starts its lifecycle from scratch!
I've made changes to the SmObjectFactory:

public class NewObjectFactory
    {
        public static IContainer Container { get; set; }

        static NewObjectFactory()
        {
            Container = new Container();
            Container.Configure(ioc =>
            {
                ioc.AddRegistry<AutomapperRegistry>();
                ioc.Scan(scan =>
                {
                    scan.AssemblyContainingType<CusomProfile>();
                    scan.WithDefaultConventions();
                    scan.AddAllTypesOf<Profile>().NameBy(item => item.FullName);
                });
                ioc.For<IUnitOfWork>()
                   .HybridHttpOrThreadLocalScoped()
                   .Use<ApplicationDbContext>()
                    // Remove these 2 lines if you want to use a connection string named connectionString1, defined in the web.config file.
                   .Ctor<string>("connectionString")
                   .Is("Data Source=(local);Initial Catalog=TestDbIdentity;Integrated Security = true");
                /*.Ctor<string>().Is(HttpContext.Current.User.Identity.Name ?? "anonymouse");*/

                ioc.For<ApplicationDbContext>().HybridHttpOrThreadLocalScoped()
                   .Use(context => (ApplicationDbContext)context.GetInstance<IUnitOfWork>());
                ioc.For<DbContext>().HybridHttpOrThreadLocalScoped()
                   .Use(context => (ApplicationDbContext)context.GetInstance<IUnitOfWork>());

                ioc.For<IUserStore<ApplicationUser, int>>()
                    .HybridHttpOrThreadLocalScoped()
                    .Use<UserStore<ApplicationUser, CustomRole, int, CustomUserLogin, CustomUserRole, CustomUserClaim>>();

                ioc.For<IRoleStore<CustomRole, int>>()
                    .HybridHttpOrThreadLocalScoped()
                    .Use<RoleStore<CustomRole, int, CustomUserRole>>();

                ioc.For<IAuthenticationManager>()
                      .Use(() => HttpContext.Current.GetOwinContext().Authentication);

                ioc.For<IApplicationSignInManager>()
                      .HybridHttpOrThreadLocalScoped()
                      .Use<ApplicationSignInManager>();

                ioc.For<IApplicationRoleManager>()
                      .HybridHttpOrThreadLocalScoped()
                      .Use<ApplicationRoleManager>();

                // map same interface to different concrete classes
                ioc.For<IIdentityMessageService>().Use<SmsService>();
                ioc.For<IIdentityMessageService>().Use<EmailService>();

                ioc.For<IApplicationUserManager>().HybridHttpOrThreadLocalScoped()
                   .Use<ApplicationUserManager>()
                   .Ctor<IIdentityMessageService>("smsService").Is<SmsService>()
                   .Ctor<IIdentityMessageService>("emailService").Is<EmailService>()
                   .Setter<IIdentityMessageService>(userManager => userManager.SmsService).Is<SmsService>()
                   .Setter<IIdentityMessageService>(userManager => userManager.EmailService).Is<EmailService>();

                ioc.For<ApplicationUserManager>().HybridHttpOrThreadLocalScoped()
                   .Use(context => (ApplicationUserManager)context.GetInstance<IApplicationUserManager>());

                ioc.For<ICustomRoleStore>()
                      .HybridHttpOrThreadLocalScoped()
                      .Use<CustomRoleStore>();

                ioc.For<ICustomUserStore>()
                      .HybridHttpOrThreadLocalScoped()
                      .Use<CustomUserStore>();

                //config.For<IDataProtectionProvider>().Use(()=> app.GetDataProtectionProvider()); // In Startup class
                // custom config

                ioc.Policies.SetAllProperties(y =>
                {
                    y.OfType<IUnitOfWork>();
                    y.OfType<IApplicationUserManager>();
                });

                configureAutoMapper(Container);
            });
        }
        private static void configureAutoMapper(IContainer container)
        {
            // automapper stuff
        }
    }

So in the Global.asax I've added these lines of code for using nested container:

public IContainer Container
{
            get
            {
                return (IContainer)HttpContext.Current.Items["_Container"];
            }
            set
            {
                HttpContext.Current.Items["_Container"] = value;
            }
}
public void Application_BeginRequest()
{
            Container = NewObjectFactory.Container.GetNestedContainer();
        }
        public void Application_EndRequest()
        {
                Container.Dispose();
                Container = null;
}

And inside Application_Start:

DependencyResolver.SetResolver(
                new StructureMapDependencyResolver(() => Container ?? NewObjectFactory.Container));

And in the DependencyResolver I've implemented the factory function this way:

public class StructureMapDependencyResolver : IDependencyResolver
{
            private readonly Func<IContainer> _factory;

            public StructureMapDependencyResolver(Func<IContainer> factory)
            {
                _factory = factory;
            }

            public object GetService(Type serviceType)
            {
                if (serviceType == null)
                {
                    return null;
                }

                var factory = _factory();

                return serviceType.IsAbstract || serviceType.IsInterface
                    ? factory.TryGetInstance(serviceType)
                    : factory.GetInstance(serviceType);
            }

            public IEnumerable<object> GetServices(Type serviceType)
            {
                return _factory().GetAllInstances(serviceType).Cast<object>();
            }
}

Finaly when I run the application I get this error:
No default Instance is registered and cannot be automatically determined for type 'Microsoft.Owin.Security.DataProtection.IDataProtectionProvider'
But when I comment this line in the Startup.cs file:

ConfigureAuth(app)

everything works and this time the ApplicationDbContext is created once and then disposed. So that's what I want: Only a single instance of the context is created now and it is correctly disposed of at the end of the web request, It means that the nested container reused the context to satisfy the dependencies of both controllers. :)
Any idea?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.