我在注入服务时遇到问题。我有一个ISettingService。我正在我的应用程序上测试注册,并使用电子邮件确认。
因此,在继承自IIdentityMessageService 的EmailMessageService类
我用Unity做Ioc。我在unity配置中注册了ISettingService,如下
.RegisterType<ISettingService, SettingService>()
我需要将此接口注入EmailMessageService类以访问设置。
这是EmailMessageService类
public class EmailMessagingService : IIdentityMessageService
{
private ISettingService SettingService { get; set; }
public Task SendAsync(IdentityMessage message)
{
var fromEmailAddress = ConfigurationManager
.AppSettings["IdentityFromEmailAddress"];
var text = message.Body;
var html = message.Body;
// Do whatever you want to the message
using (var msg = new MailMessage())
{
msg.From = new MailAddress(fromEmailAddress);
msg.To.Add(new MailAddress(message.Destination));
msg.Subject = message.Subject;
msg.AlternateViews.Add(
AlternateView.CreateAlternateViewFromString(
text, null, MediaTypeNames.Text.Plain)
);
msg.AlternateViews.Add(
AlternateView.CreateAlternateViewFromString(
html, null, MediaTypeNames.Text.Html)
);
// var smtpClient = new SmtpClient("smtp.whatever.net", Convert.ToInt32(587));
// var credentials = new System.Net.NetworkCredential(Keys.EmailUser, Keys.EMailKey);
// smtpClient.Credentials = credentials;
using (var smtpClient = new SmtpClient())
{
var setting = SettingService.Query().Select().FirstOrDefault();
if (setting != null)
{
if (!string.IsNullOrEmpty(setting.SmtpHost))
{
smtpClient.Host = setting.SmtpHost;
smtpClient.Port = Convert.ToInt32(setting.SmtpPort);
if (setting.IsSmtpSsl)
{
smtpClient.EnableSsl = true;
}
}
}
smtpClient.Send(msg);
}
}
return Task.FromResult(0);
}
}
EmailMessageService类在Startup.Auth 上实例化
var manager =
new ApplicationUserManager(
new ApplicationUserStore(context.Get<DataContext>()));
...
manager.EmailService = new EmailMessagingService();
我不能使用构造函数注入作为这个直接调用的原因。所以我使用了setter注入。但我得到了类似"对象引用未设置为对象实例"的错误
var setting = SettingService.Query().Select().FirstOrDefault();
在EmailMessageService中。
O.K我不知道发生了什么,但通过更改UnityMvcActivator Start方法,如下所示。
public static void Start()
{
var container = ContainerManager.GetConfiguredContainer();
UnityConfig.RegisterTypes(container);
FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container));
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
try
{
//http://stackoverflow.com/questions/699852/how-to-find-all-the-classes-which-implement-a-given-interface
foreach (var assembly in assemblies)
{
var instances = from t in assembly.GetTypes()
where t.GetInterfaces().Contains(typeof(IDependencyRegister))
&& t.GetConstructor(Type.EmptyTypes) != null
select Activator.CreateInstance(t) as IDependencyRegister;
foreach (var instance in instances.OrderBy(x => x.Order))
{
instance.Register(container);
}
}
}
catch (ReflectionTypeLoadException ex)
{
http://stackoverflow.com/questions/1091853/error-message-unable-to-load-one-or-more-of-the-requested-types-retrieve-the-l
System.Text.StringBuilder sb = new System.Text.StringBuilder();
foreach (Exception exSub in ex.LoaderExceptions)
{
sb.AppendLine(exSub.Message);
System.IO.FileNotFoundException exFileNotFound = exSub as System.IO.FileNotFoundException;
if (exFileNotFound != null)
{
if (!string.IsNullOrEmpty(exFileNotFound.FusionLog))
{
sb.AppendLine("Fusion Log:");
sb.AppendLine(exFileNotFound.FusionLog);
}
}
sb.AppendLine();
}
string errorMessage = sb.ToString();
throw new Exception(errorMessage, ex);
//Display or log the error based on your application.
}
// TODO: Uncomment if you want to use PerRequestLifetimeManager
// Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
}